剑指架构师系列-InnoDB存储引擎、Spring事务与缓存
事务与锁是不同的。事务具有ACID属性:
原子性:持久性:由redo log重做日志来保证事务的原子性和持久性,
一致性:undo log用来保证事务的一致性
隔离性:一个事务在操作过程中看到了其他事务的结果,如幻读。锁是用于解决隔离性的一种机制。事务的隔离级别通过锁的机制来实现。
数据库的事务隔离级别有(多个事务并发的情况下):
√: 可能出现 ×: 不会出现
|
事务的隔离级别
|
脏读 事务1更新了记录,但没有提交,事务2读取了更新后的行,然后事务T1回滚,现在T2读取无效。违反隔离性导致的问题,添加行锁实现 | 不可重复读 事务1读取记录时,事务2更新了记录并提交,事务1再次读取时可以看到事务2修改后的记录(修改批更新或者删除)需要添加行锁进行实现 | 幻读 事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录。需要添加表锁进行实现 |
| Read uncommitted | √ | √ | √ |
| Read committed | × | √ | √ |
| Repeatable read | × | × | √ |
| Serializable | × | × | × |
对应着Spring中的5个事务隔离级别(通过lsolation的属性值指定)
1、default 默认的事务隔离级别。使用的是数据库默认的事务隔离级别
2、read_uncommitted 读未提交,一个事务可以操作另外一个未提交的事务,不能避免脏读,不可重复读,幻读,隔离级别最低,并发性能最高
3、read_committed(脏读) 大多数数据库默认的事务隔离级别。读已提交,一个事务不可以操作另外一个未提交的事务, 能防止脏读,不能避免不可重复读,幻读
4、repeatable_read(不可重复读) innodb默认的事务隔离级别。能够避免脏读,不可重复读,不能避免幻读
5、serializable(幻读) innodb存储引擎在这个级别才能有分布式XA事务的支持。隔离级别最高,消耗资源最低,代价最高,能够防止脏读, 不可重复读,幻读
Spring中的事务完全基于数据库的事务,如果数据库引擎使用MyISAM引擎,那Spring的事务其实是不起作用的。另外,Spring为开发者提供的与事务相关的特性就是事务的传播行为,如下:
|
事务传播行为类型 |
说明 |
|
propagation_required |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择(Spring默认的事务传播行为) |
|
propagation_supports |
支持当前事务,如果当前没有事务,就以非事务方式执行 |
|
propagation_mandatory(托管) |
使用当前的事务,如果当前没有事务,就抛出异常 |
|
propagation_requireds_new |
新建事务,如果当前存在事务,把当前事务挂起 |
|
propagation_not_supported |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 |
|
propagation_never |
以非事务方式执行,如果当前存在事务,则抛出异常 |
|
propagation_nested |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作,也就是新建一个事务 |
Spring通过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中。
Spring可以配置事务的属性,但是隔离级别、读写事务属性、超时时间与回滚设置等都交给了JDBC,真正自己实现的只有事务的传播行为。那么什么时候发生事务的传播行为呢?
public class ForumService {
private UserService userService;
@Transactional(propagation = Propagation.REQUIRED)
public void addTopic() {
// add Topic
this.updateTopic();
userService.addCredits();
}
@Transactional(propagation = Propagation.REQUIRED)
public void updateTopic() {
// add Topic
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
看一下userService中的addCredits()方法,如下:
public class UserService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addCredits() {
}
}
然后测试下:
forumService.addTopic();
开启了Spring4日志的DEBUG模式后,输出如下:
- Returning cached instance of singleton bean 'txManager' - Creating new transaction with name [com.baobaotao.service.ForumService.addTopic]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] for JDBC transaction - Switching JDBC Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] to manual commit - Suspending current transaction, creating new transaction with name [com.baobaotao.service.UserService.addCredits] - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] for JDBC transaction - Switching JDBC Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] to manual commit - Initiating transaction commit - Committing JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] - Releasing JDBC Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] after transaction - Returning JDBC Connection to DataSource - Resuming suspended transaction after completion of inner transaction - Initiating transaction commit - Committing JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] - Releasing JDBC Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] after transaction - Returning JDBC Connection to DataSource
清楚的看到只有调用addCredis()方法时发生了事务的传播行为,而同一个类内的方法没有发生。在我们阅读了源代码后就可以知道这是为什么以及什么时候会发生传播行为了。
另外一点:决定事务传播行为是由首次调用有事务的方法决定的。如上例子中的事务传播行为由addTopic()方法来决定。
在使用事务中我们需要做到尽量避免死锁、尽量减少阻塞,根据不同的数据库设计和性能要求进行所需要的隔离级别,才是最恰当的。具体以下方面需要特别注意:
A、 事务操作过程要尽量小,能拆分的事务要拆分开来
B、 事务操作过程不应该有交互(系统交互,接口调用),因为交互等待的时候,事务并未结束,可能锁定了很多资源
C、 事务操作过程要按同一顺序访问对象。(避免死锁的情况产生)
D、 提高事务中每个语句的效率,利用索引和其他方法提高每个语句的效率可以有效地减少整个事务的执行时间。
E、 查询时可以用较低的隔离级别,特别是报表查询的时候,可以选择最低的隔离级别(未提交读)。
剑指架构师系列-InnoDB存储引擎、Spring事务与缓存的更多相关文章
- 剑指架构师系列-MySQL调优
介绍MySQL的调优手段,主要包括慢日志查询分析与Explain查询分析SQL执行计划 1.MySQL优化 1.慢日志查询分析 首先需要对慢日志进行一些设置,如下: SHOW VARIABLES LI ...
- 剑指架构师系列-Struts2的缓存
Struts2的缓存中最重要的两个类就是ReferenceMap与ReferenceCache.下面来解释下ReferenceCache中的get()方法. public V get(final Ob ...
- 剑指架构师系列-spring boot的logback日志记录
Spring Boot集成了Logback日志系统. Logback的核心对象主要有3个:Logger.Appender.Layout 1.Logback Logger:日志的记录器 主要用于存放日志 ...
- 剑指架构师系列-持续集成之Maven+Nexus+Jenkins+git+Spring boot
1.Nexus与Maven 先说一下这个Maven是什么呢?大家都知道,Java社区发展的非常强大,封装各种功能的Jar包满天飞,那么如何才能方便的引入我们项目,为我所用呢?答案就是Maven,只需要 ...
- 剑指架构师系列-tomcat6通过IO复用实现connector
由于tomcat6的配置文件如下: <Connector port="80" protocol="org.apache.coyote.http11.Http11Ni ...
- 剑指架构师系列-Struts2构造函数的循环依赖注入
Struts2可以完成构造函数的循环依赖注入,来看看Struts2的大师们是怎么做到的吧! 首先定义IBlood与BloodImpl类: public interface IBlood { } pub ...
- 剑指架构师系列-tomcat6通过伪异步实现connector
首先在StandardService中start接收请求的线程,如下: synchronized (connectors) { for (int i = 0; i < connectors.le ...
- 剑指架构师系列-Hibernate需要掌握的Annotation
1.一对多的关系配置 @Entity @Table(name = "t_order") public class Order { @Id @GeneratedValue priva ...
- 剑指架构师系列-Linux下的调优
1.I/O调优 CentOS下的iostat命令输出如下: $iostat -d -k 1 2 # 查看TPS和吞吐量 参数 -d 表示,显示设备(磁盘)使用状态:-k某些使用block为单位的列强制 ...
随机推荐
- 關於imagick不得不說的一些事
PHP建圖通常都用GD庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就不建議用GD了,因為GD不但低效能而且能力也比較弱,佔用的系統資源 ...
- typeid详解
在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“ ...
- WindowsPhone-GameBoy模拟器开发六--[转]指令系统实现必读:补码
网上有同行写了些好文章,在此就不现丑了,贴上连接,放在这里为了补充系列的完整性 计算机为什么选用二进制补码 为什么补码重要?因为计算机中内存.寄存器里面存的数都是用补码表示的!
- win7下虚拟机安装mac 转载自 http://itbbs.pconline.com.cn/50602805.html
最近,不断有人问起,如何在vmware下安装MAC系统.起因是以前曾发过一篇贴,在vmware8下安装MAC的方法.于是,重新下载了最新版苹果系统10.8.5,终于成功安装.现将注意事项及过程与各位朋 ...
- struts1+spring+myeclipse +cxf 开发webservice以及普通java应用调用webservice的实例
Cxf + Spring+ myeclipse+ cxf 进行 Webservice服务端开发 使用Cxf开发webservice的服务端项目结构 Spring配置文件applicationCont ...
- C变量类型和作用域
C语言中所有变量都有自己的作用域,申明变量的类型不同,其作用域也不同.C语言中的变量,按照作用域的范围可分为两种, 即局部变量和全局变量. 一.局部变量 局部变量也称为内部变量.局部变量是在函数内作定 ...
- TCP/IP 网络编程 (三)
server端未处理高并发请求通常採用例如以下方式: 多进程:通过创建多个进程提供服务 多路复用:通过捆绑并统一管理 I/O 对象提供服务 多线程:通过生成和客户端等量的线程提供服务 多进程serve ...
- IPv6 app适配
参考资料: https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/Network ...
- 卖萌的极致!脸部捕捉软件FaceRig让你化身萌宠
FaceRig是一款以摄像头为跟踪设备捕捉用户脸部动作并转化为数据套用在其他动画模型上的一款软件,能够应用于一些日常的视频社交软件或网站,比如视频通话软件Skype和直播网站Twitch.FaceRi ...
- Cocos2d-JS项目之三:使用合图
studio里使用合图感觉和spriteBatchNode差不多,但有不同,合图只起到在加载资源时减少IO的作用,起不到批渲染的作用.其实想想,studio本来就是用来拼UI界面的,一个上点规模的UI ...