事物及其隔离级别

1.1 模拟转账

生活当中转账是转账方账户扣钱,收账方账户加钱。我们用数据库操作来模拟现实转账。

1.1.1 数据库模拟转账

 

#A 账户转账给 B 账户 1000 元。
#A 账户减1000 元
UPDATE account SET MONEY = MONEY-1000 WHERE id=1;
​
#B 账户加 1000 元
UPDATE account SET MONEY = MONEY+1000 WHERE id=2;

1.1.2 模拟转账错误

#A 账户转账给 B 账户 1000 元。
#A 账户减1000 元
UPDATE account SET MONEY = MONEY-1000 WHERE id=1;
#断电、异常、出错...
​
#B 账户加 1000 元
UPDATE account SET MONEY = MONEY+1000 WHERE id=2;

1.2 事务的概念

事务是一个原子操作。是一个最小执行单元。可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败。

1.3 事务的边界

  • 开始:连接到数据库,执行一条DML语句。 上一个事务结束后,又输入了一条DML语句,即事务的开始

  • 结束:

    ​ 1). 提交:

    ​ a. 显示提交:commit;

    ​ b. 隐式提交:一条创建、删除的语句,正常退出(客户端退出连接);

    ​ 2). 回滚:

    ​ a. 显示回滚:rollback;

    ​ b. 隐式回滚:非正常退出(断电、宕机),执行了创建、删除的语句,但是失败了,会为这个无效的语句执行回滚。

1.4 事务的原理

数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个事务中所有的增删改语句的执行结果都会缓存在回滚段中,只有当事务中所有SQL语句均正常结束(commit),才会将回滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将回滚(rollback)。

1.5 事务的特性

    表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败

    表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态

    事务查看数据操作时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

事务的隔离性可以分为4种类型的隔离级别:

                ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

                ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

                ③ Read committed (读已提交):可避免脏读的发生。

                ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

    持久性事务完成之后,它对于系统的影响是永久性的。

1.6 事务应用

应用环境:基于增删改语句的操作结果(均返回操作后受影响的行数),可通过程序逻辑手动控制事务提交或回滚

1.6.1 事务完成转账

#A 账户给 B 账户转账。
#1.开启事务
START TRANSACTION;
set AutoCommit=0;#禁止自动提交( set AutoCommit=1;#开启自动提交)
#2.事务内数据操作语句
UPDATE ACCOUNT SET MONEY = MONEY-1000 WHERE ID = 1;
UPDATE ACCOUNT SET MONEY = MONEY+1000 WHERE ID = 2;
#3.事务内语句都成功了,执行 COMMIT;
COMMIT;
#4.事务内如果出现错误,执行 ROLLBACK;
ROLLBACK;

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring事务隔离级别默认是Isolation.DEFAULT,即采用数据库默认的事务隔离级别。但是Spring支持设置多种隔离级别,包括: - Isolation.READ_UNCOMMITTED:读取未提交数据,具有最低的隔离级别,存在脏读、不可重复读和幻读的问题。 - Isolation.READ_COMMITTED:读取已提交数据,解决了脏读问题,但仍然存在不可重复读和幻读的问题。 - Isolation.REPEATABLE_READ:可重复读,解决了脏读和不可重复读问题,但仍然存在幻读问题。 - Isolation.SERIALIZABLE:串行化,隔离级别最高,避免了所有并发问题。 Spring使用@Transactional注解来设置事务隔离级别,示例如下: ```java @Service @Transactional(isolation = Isolation.READ_COMMITTED) public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public void transfer(String fromUser, String toUser, int amount) throws Exception { User from = userDao.findByName(fromUser); User to = userDao.findByName(toUser); if (from.getBalance() < amount) { throw new RuntimeException("余额不足"); } from.setBalance(from.getBalance() - amount); to.setBalance(to.getBalance() + amount); userDao.update(from); userDao.update(to); } } ``` 在上述代码中,@Transactional注解的isolation属性设置为Isolation.READ_COMMITTED,表示采用读取已提交数据的隔离级别。在transfer方法中,多个线程同时进行转账操作时,会采用该事务隔离级别来保证数据的一致性和正确性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值