MySQL 事务
引言
MySQL事务主要用于处理操作量大,复杂度高的数据,比如说,,在人员管理系统中,两个用户同时删除某个人员时,等等,这样就构成了一个事务.
特点
- 在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务.
- 事务处理可以用来维护数据的完整性,保证呈批的SQL语句要么全部执行,要么全不执行
- 事务用来管理insert,update,delete语句
一般来说,事务是必须满足四个条件:
- 原子性(Atomicity,或不可分割性): 一个事务中的所有操作,妖魔全部完成,要么全不完成,不会结束中间摸个环节,事务在执行过程中发生错误,会被回滚(Rillback)到事务开始前的状态,就想这个事务从来没有执行过一样.
- 一致性(Consistency): 在事务开始之前和事务结束以后,数据库的完整性没有被破坏.这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度,串联性以及后续数据库可以自由行的完成预定工作.
- 隔离性(Lsolation,又称独立性): 数据库允许多个并发事务同时对其数据库进行读写和修改的能力,隔离性可以防止多个事务并发执行由于交叉执行而导致数据不一致,事务隔离分别为不同级别,包括
未提交
,读提交
,可重复读
和串行化
- 持久性(Durability): 事务处理结束后,对数据的修改就是永久的即便系统故障也不会丢失.
Spring的事务机制
JAVA EE传统事务机制
通常有两种事务策略:
全局事务
和局部事务
.全局事务可以跨多个事务性资源(即数据源,典型的是数据库和消息队列),通常都需要J2EE应用服务器的管理,其底层需要服务器的JTA支持.而局部事务则与底层采用的持久化技术有关,如果底层直接使用JDBC,需要使用Connection
队形来操作事务,如果采用Hibernate
持久化技术,则需要使用session对象来操作事务.
通常的,使用JTA事务,JDBC事务及Hibernate
事务的变成就成大致如下
上图也可以看出,采用传统事务变成,程序代码必须和具体的事务策略API耦合,如果应用需要切换一种策略,意味着需要大幅修改代码,但是如果使用Spring事务的话,就不会有这个问题了
Spring事务机制
Spring没有提供任何事物支持,他只是负责包装底层的事务,而在Spring层面,对外提供统一的编程API.Spring事务的核心是PlatformTransactionManager
接口.
PlatformTransactionManager
代表与具体类型无关的事务接口,可以代表任何事,包括JDBC事务,Hibernate事务,甚至是JTA事务
Spring事务机制是一种典型的策略模式,PlatformTransactionManager
代表事务管理接口,蛋挞并不知道到底如何管理事务,他只要求事务管理员提供开始事务getTransaction(),提交事务commit()和回滚事务roolback()这是哪个方法,但具体如何实现交给其实现类完成.变成人员只需要在配置文件中根据具体需要使用的事务类型做配置,,Stpring 底层就会自动回使用具体的事务实现类进行事务操作,而对于程序员来说,完全不需要关心底层,是需要xiangPlatformTransactionManager接口进行变成即可PlatformTransactionmanager接口中提供了如下方法:getTransaction(...),commit();rollback这些都是与平台无关的事务操作.
getTransaction()完整的写法为TransactionStatus get Transcation(TransactionDefinition definiton)
这个方法用来返回一个事务对象,其中参数TransactionDefintion则可以为事务对象指定各种属性,通常可以指定事务的隔离性,传播属性,超市,制度这几个属性
使用
一种方法是使用XML文件进行配置
另一种是我常用改的方法,比较简单直接在方法上添加@Transaction注解(我多用在service类中),使这个方法具有事务属性,在@Transaction中可以为事务配置各种睡醒(例如隔离性,传播性,超市,只读属性等等),此外,还需要在XML配置中假如<>
@Transactional(readOnly = false, rollbackFor = Exception.class)
public String add() {
...
}
手动回滚
当我使用阿里云代码约束规范的时候,会这样提示,所以加上这个注解就好了
spring手动回滚事务:
@Transactional(rollbackFor = { Exception.class })
public String methods() {
String str = "-----------";
try {
doSomethings......
} catch (Exception e) {
logger.error("e.getMessage()", e);
//手动开启事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return str;
}