JavaWeb基础—JDBC(二)事务与批处理
一、批处理
这里给出PrepareStatement的示例,优点是可以发送预编译的SQL,缺点是SQL语句无法更换,但参数可以更换
批处理:多条语句的处理
mysql默认是关闭的,要打开需要在url后加参数
url?rewriteBatchedStatements=true
这里介绍pstmt(stmt的批处理略),利用循环疯狂向里面添加参数
for(int i=0;i<=10;i++){
//为字段赋值
ps.setInt(1, i+1);
ps.setString(2, "name"+i);
ps.setInt(3, 10+i);
//添加进批,上车
ps.addBatch();
if(i%10==0){
//发车
ps.executeBatch();
//下车
ps.clearBatch();
}
i%2==0?"":""省得使用判断
二、事务
1.事务的概念
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组
事务的两类更新丢失:http://java7.blog.51cto.com/2132766/1557753
事务:(拿转账accont转账)原子性:不可再分割
事务的特性(ACID特性)
A:原子性(Atomicity)
事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
转账不能只完成一半,不能只扣钱不加钱!
B:一致性(Consistency)最重要的特性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
转账前转账后账户和不能变
C:隔离性(Isolation)
一个事务的执行不能被其他事务干扰。
多个数据并发操作时要隔离开来
不能站排,不然效率过低
D:持续性/永久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
即使是崩溃了,也要能够恢复回来
这里对隔离进行一点展开:
JDBC事务隔离级别产生的问题(需要注意的是,只有在并发的情况下才会有事务隔离产生的问题)
1,脏读(最可怕的)
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
A给B转账100,B收到了,但此时A再回滚,脏读!
2,不可重复读(有时候是允许的)
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却
返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
3,虚读(幻读)(有时候也是允许的)
幻读是事务非独立执行时发生的一种现象。对同一张表两次查询不一致,因为另外
一个事务做了插入(或删除)的操作
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),
所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体
(比如数据的个数)。
现在来看看MySQL数据库为我们提供的四种隔离级别:
隔离模式
READ UNCOMMITTED
不隔离SELECT
其他事务未完成的修改(未COMMIT),其结果也考虑在内
READ COMMITTED
把其他事务的 COMMIT 修改考虑在内
同一个事务中,同一 SELECT 可能返回不同结果
REPEATABLE READ(默认)
不把其他事务的修改考虑在内,无论其他事务是否用COMMIT命令提交过
同一个事务中,同一 SELECT 返回同一结果(前提是本事务,不修改)
SERIALIZABLE
和REPEATABLE READ类似,给所有的SELECT都加上了 共享锁
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
(但性能差,连并发都没了,哪来并发问题,已发生死锁,坚决不用)
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。不处理幻读问题
(MySQL默认)
③ Read committed (读已提交):可避免脏读的发生。
(Oracal默认)
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
mysql数据库查询当前事务隔离级别:select @@tx_isolation
mysql数据库设置事务隔离级别:set transaction isolation level 隔离级别名
详细的事务的实例级别的讲解,请参见Jelly_lyj的博文:http://www.cnblogs.com/snsdzjlz320/p/5761387.html
关于共享锁和排他锁可以参见:http://blog.csdn.net/pingnanlee/article/details/41824389
关于之前产生的锁和隔离级别的关系的困惑,参考:http://blog.csdn.net/zdp072/article/details/51100593
2.MySQL中的事务:
开启事务:start transaction
关闭事务:commit或rollback
3.JDBC中的事务:
JDBC中处理事务都是通过Connection对象完成的,同一事务中所有的操作使用的都是
【同一个】con对象!
DAO层方法使用外面传递的con,这样每次事务都是同一个!
1.setAutoCommit(boolean autoCommit) 为false时开启
将此连接的自动提交模式设置为给定状态。
2.con.rollback()
取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的
所有数据库锁
3.con.commit()
使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前
持有的所有数据库锁。
在开发中,有时候可能需要手动设置事务的回滚点,在JDBC中使用如下的语句设置事务回滚点
Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit();//回滚后必须通知数据库提交事务
常用的模式
try{
con.setAutoCommit(false);//开启事务
...
con.commit();//最后的提交事务
//通常提交完后关闭连接
con.close();
}catch(){
con.rollback();//业务回滚
}finally{}
写个数据库等的相关的小项目等都需要一点准备工作:
导包,导配置文件等。。。