暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

第9讲:事务的介绍和使用

何先振 2024-06-11
85

以下文章来源于何先振,责编小何


事务问题引入



当我们使用JDBC技术操作数据库的时候,需要实现一个业务逻辑。往往我们会给数据库发送多条SQL语句。


例如,转账业务逻辑,我们新建一张用户账户表。





添加两个账户信息。





要想完成转账业务逻辑,张三给李四转账100元。


需要修改张三的账户信息减100,李四的账户信息加100。这里涉及到两个update的语句。





执行这两条SQL,成功完成了转账操作。





但是这是理想情况,两条SQL语句都执行成功了。


在Java程序中使用JDBC操作数据库时,很容易因为一些错误,导致一个SQL执行成功,一个SQL执行不成功,影响到我们的业务逻辑出错。


例如:我们通过前面几节封装的通用工具类实现转账功能。中间模拟一个网络异常。





调用的是工具类中通用增删改的方法。





执行后发现,程序出错。





转账业务逻辑出现错误,张三减去的100元,没有加到李四上,直接消失了。






按照正常逻辑:要么转账成功,要么转账失败。如果转账失败需要把钱退回张三的账户上。


为了业务逻辑能正常,我们需要通过数据库的事务来保证。



数据库事务介绍



什么是数据库事务呢?


事务是一组逻辑操作的单元,使数据从一种状态变成另外一种状态。


一组逻辑操作的单元:就是一个或多个SQL操作。


例如:刚刚转账就是两个update的操作。这两个update看成一个整体构成了一个事务,实现了这个转账的业务逻辑。


从一种状态变成另外一种状态:就是事务执行的结果,只会有两种状态要么转账成功,张三少了一百,李四多了一百要么转账失败,张三钱没变,李四钱也没变。


这也是事务的原则,保证所有事务都可以作为一个工作单元来执行,即使出现问题也不能改变这种执行方式。要么全部执行成功被提交,要么全部执行失败事务被回滚。


默认情况下,MySQL会把每一条DML语句当成一个事务,一旦执行就会自动提交。


我们可以修改这种默认规则,改成手动提交事务。


如果执行成功就提交事务,如果执行过程中出现异常就回滚事务。但是注意要保证这组SQL操作完才关闭连接。因为关闭连接也会导致事务提交。


通过事务解决问题


修改事务手动提交实现转账功能,首先需要获取连接对象。通过setAutoCommit(false),关闭自动提交事务。





然后利用方法的重载,在新建一个工具类的通用增删改方法,新增连接对象入参。因为一个事务要共用一个连接对象。





将原来执行完关闭资源的方法,连接对象修改为null,因为要保证一个事务的SQL都被执行完了才关闭。





最终重载支持事务的通用增删改方法:





调用修改好的通用增删改方法。





没有出现异常,手动提交事务。使用commit()方法。





如果出现异常了,使用rollback()方法回滚事务。





最后都执行完了,才关闭连接。





没转账之前的用户账户金额。





中间模拟了网络异常。





执行程序,程序出现异常。





转账失败,数据库事务回滚,数据还是跟没转账时一样。





去掉模拟网络异常的代码。





执行程序,转账成功。





金额正常被转了过去。





注意点:


DML语句我们是可以取消他的默认事务提交机制,改成手动控制提交。但是DDL语句是不行的。每次创建一个表就会自动提交事务。


如果使用了数据库连接池,我们关闭了连接对象,连接对象会被放回到池子里,给其它事务使用。


所以如果设置了手动提交事务,关闭资源时需要恢复默认,避免影响其它事务使用这个连接对象。





至于什么是数据库连接池,后面章节会接着讲解。



扫码进微信答疑群




点击上方"何先振"关注并选择设为星标
各类IT技术文章不会错过!

文章转载自何先振,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论