java jdbc 事务_【Java学习】JDBC事务

概述

在开发中,我们对数据库的多个表或对一个表的多条数据执行更新操作的时候,要保证多个更新操作要么同时成功、要么都不成功。这就涉及到多个更新操作的事务管理问题了。

例如:银行的转账问题,A用户向B用户转账100元,假设A用户和B用户的钱都存储在Account表中,那么A向B转账就涉及同时更新Account表中的A用户的钱和B用户的钱,不然的话,A的钱少了,而B却没有收到钱,这是不允许出现的事件。

update account set money = money -100 where name = 'A';

update account set money = money + 100 where name = 'B';

事务

为什么上面的sql语句不能够实现“要么都成功、要么都失败”?这是因为如果JDBC处于自动提交模式,每个SQL语句在完成后都会提交到数据库,也就是说在执行A扣钱(即第一条sql)语句之后,他就已经更新了数据库,如果这个时候程序突然崩溃,导致后面的语句没有运行,那么就出现了我们说的,a扣钱了,但是b却没收到钱。

所以我们需要考虑是否关闭自动提交并且管理自己的事务。

事务能够控制何时更改提交并应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,整个事务将失败。

如上面所说,JDBC连接默认是处于自动提交,我们需要手动的打开这个功能。调用Connection对象的setAutoCommit()方法,将false传递给setAutoCommit(),就关闭了自动提交。也可以创第一个布尔值true来打开它。

conn.setAutoCommit(false);

现在我们知道了,想要让多条更新语句保持原子性,首先要关闭自动提交,然后手动提交,在一个事务失败的时候,要进行回滚。

提交和回滚

完成更改后,若要提交更改,需要在对象上调用commit()方法:

conn.commit();

否则要进行回滚

conn.rollback();

以下实例说明了如何使用提交和回滚。

try{

conn.setAutoCommit(false);

Statement stmt = conn.createStatement();

String SQL = "INSERT INTO Employees" + "VALUES (106,20,'Rita,'Tez')";

stmt.executeUpdate(SQL);

String SQL = "IMSERT IN Employees " + "VALUES (107,22,'SITA','SINGH')";

stmt.excuteUpdate(SQL);

conn.commit();

}catuch(SQLException se){

conn.rollback();

}

使用保存点

新的JDBC3.0新添加了Savepoint接口提供了额外的事务控制能力。

使用Connection对象两个方法来创建Savepoint对象。

setSavepoint(String savepointName);//定义新的保存点,返回`Savepoint`对象。

releaseSavepoint(Savepoint savepointName);//删除保存点。参数是由上面的方法生出的对象。

这样使用rollback(String savepointName)方法,就可以将事务回滚到指定的保存点

try{

//Assume a valid connection object conn

conn.setAutoCommit(false);

Statement stmt = conn.createStatement();

//set a Savepoint

Savepoint savepoint1 = conn.setSavepoint("Savepoint1");

String SQL = "INSERT INTO Employees " +

"VALUES (106, 24, 'Curry', 'Stephen')";

stmt.executeUpdate(SQL);

//Submit a malformed SQL statement that breaks

String SQL = "INSERTED IN Employees " +

"VALUES (107, 32, 'Kobe', 'Bryant')";

stmt.executeUpdate(SQL);

// If there is no error, commit the changes.

conn.commit();

}catch(SQLException se){

// If there is any error.

conn.rollback(savepoint1);

}

事务的隔离性

以上我们说明了,如何实现一个数据要么都成功,要么都失败,这个其实是在事务中的原子性。而另一个比较重要的就是隔离性

什么是隔离性

所谓隔离性是指事务与事务之间的隔离,即在事务提交之间,其他事务中与未完成的事务的数据中间状态访问权限,具体可以通过设置隔离级别来进行控制。

并发事务可能出现的情况

脏读

一个事务读取另一个事务尚未提交的数据。

5931dc86f56b766f61070cd4f868935a.png

这个解决办法,就是在事务进行操作的时候,禁止该事物进行读操作。

不可重新读

其他事务的操作导致某一个事务两次读取数据不一致。

619c9c67ab2039b236d94b2d3f56c789.png

幻读

其他事务的数据操作导致某个事务两次读取数据数量不一致。

参考资料

未完待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值