浅谈数据库事务(transaction)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u013007900/article/details/77927723
事务的定义
只有增删改才会用到事务 查询不会用到事务
单次的增删改也不需要用到事务:比如修改密码、上传头像
两次以上的增删改会用到事务 这是使用事务的前提
这也是死原则
没有用到事务数据回出现问题!!!!项目中的将默认值uid=3 id=180,会造成数据不安全的问题
解决方案添加@Transactional就行了,这就是事务注解
附:使用事务(Transaction)
当执行的某个业务涉及2次或更多次的增、删、改操作时,必须使用事务来保证数据安全,例如2次Update,或1次Delete与1次Update,都是需要使用事务的,而查询不涉及事务。

当需要通过事务保证数据安全时,应该在业务方法之前添加@Transactional注解。

该注解也可以添加在业务类上,表示该业务类中所有的方法都是有事务保障的,通常,还是推荐将注解添加到业务方法上。

该功能是Spring提供的(spring-jdbc),与MyBatis无关。

需要注意的是,Spring框架在处理时,类似于:

开启事务 begin
try {
执行数据操作
可能:提交 commit
} catch (RuntimeException e) {
可能:回滚 rollback
}

所以,在开发时,必须做到:

所有的增、删、改操作,在业务层调用时,必须判断返回值,如果视为操作错误,必须抛出异常;
业务层抛出的异常必须是RuntimeException的子孙类!

如果不是通过SpringBoot创建的项目,而是自行配置SSM的项目,则需要添加配置:



<tx:annotation-driven
transaction-manager=“transactionManager”/>

在这里插入图片描述
在这里插入图片描述
事务(txn)是一系列在共享数据库上执行的行为,以达到更高层次更复杂逻辑的功能。事务是DBMS中最基础的单位,事务不可分割。

ACID

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

原子性

原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

在这里插入图片描述
这里写图片描述
假设A要给B转钱,在事务中的扣款和加款两条语句,要么都执行,要么就都不执行。否则如果只执行了扣款语句,就提交了,此时突然断电,A账号已经发生了扣款,B账号却没收到加款,在生活中就会引起纠纷。

一致性

一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。

对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNT表中A和B的存款总额始终为2000元。如果一个人扣100元,一个人得50元,就破坏了一致性。

事务的一致性决定了一个系统设计和实现的复杂度。事务可以不同程度的一致性:
强一致性:读操作可以立即读到提交的更新操作。
弱一致性:提交的更新操作,不一定立即会被读操作读到,此种情况会存在一个不一致窗口,指的是读操作可以读到最新值的一段时间。
最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有错误发生,不一致窗口的大小依赖于:通信延迟,系统负载等。
其他一致性变体还有:
单调一致性:如果一个进程已经读到一个值,那么后续不会读到更早的值。
会话一致性:保证客户端和服务器交互的会话过程中,读操作可以读到更新操作后的最新值。
隔离性

多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。

这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。

并行时可能出现的问题:

脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。
幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。
不同的隔离级别:

Read Uncommitted:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
Repeated Read:在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。
隔离级别 脏读 丢失更新 不可重复读 幻读 并发模型 更新冲突检测
未提交读:Read Uncommited √ √ √ √ 悲观 ××
已提交读:Read commited ×× √ √ √ 悲观 ××
可重复读:Repeatable Read ×× ×× ×× √ 悲观 ××
可串行读:Serializable ×× ×× ×× ×× 悲观 ××
持久性

持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

即使出现了任何事故比如断电等,事务一旦提交,则持久化保存在数据库中。

猜你喜欢

转载自blog.csdn.net/qq_43165760/article/details/86140178