上次在学习项目的过程当中发现了一个这样的配置,方法事务上@Transactional(value = "transactionManager",readOnly = true)
增长了一个readOnly = true
的配置,很好奇这有什么用?原理是什么?下面我将一一说说它是什么以及在mysql、oracle中的区别。java
事务分为只读事务和读写事务,咱们第一反应会想到的含义是只读事务不容许你在一个事务中执行诸如update
、delete
、insert
的操做,你只能执行select
操做,可是,其实不是,只读事务并非必须的,你一样能够在只读事务中执行修改操做,只不过显示声明事务为只读模式,会让相应的数据库对你的事务进行一些优化操做而已。mysql
要演示只读事务对 mysql、oracle 的支持,首先要作的就是把例子给搭建起来,下面我将描述相关测试用例:git
Spring 声明式事务分为两种,一种是基于<tx>、<aop:config>
标签的事务声明,另一种是基于@Transacional
的注解声明。咱们采用第二种方式声明。github
很显然,既然你要链接到 mysql、oracle 数据库,那么你就须要相应的数据库驱动程序;因为采用 Spring 进行事务管理,那么相应的Spring 包必不可少;固然你还须要一个数据源,告诉相应的驱动程序你的数据从哪里来;最后,我就不贴出代码了,代码太多,直接在github上看便可。sql
代码github地址数据库
mysql 提供对只读事务的支持,事务的默认隔离级别为“可重复读”。session
编号 | 是否加事务 | 是否执行更新操做 | 事务是否只读 | 执行结果 |
---|---|---|---|---|
1 | 否 | 否 | 屡次执行查询,结果随数据库改变而改变 | |
2 | 否 | 是 | 屡次执行查询,结果随数据库改变而改变 | |
3 | 是 | 否 | 否 | 屡次执行查询,结果不随数据库改变而改变,读视图一致 |
4 | 是 | 是 | 否 | 屡次执行查询,结果不随数据库改变而改变,读视图一致 |
5 | 是 | 否 | 是 | 屡次执行查询,结果不随数据库改变而改变,读视图一致 |
6 | 是 | 是 | 是 | 执行更会报错,提示 readOnly |
oracle 提供对只读事务的支持,事务的默认隔离级别为“read committed”。oracle
编号 | 是否加事务 | 是否执行更新操做 | 事务是否只读 | 执行结果 |
---|---|---|---|---|
1 | 否 | 否 | 屡次执行查询,结果随数据库改变而改变 | |
2 | 否 | 是 | 屡次执行查询,结果随数据库改变而改变 | |
3 | 是 | 否 | 否 | 屡次执行查询,结果随数据库改变而改变 |
4 | 是 | 是 | 否 | 屡次执行查询,结果随数据库改变而改变 |
5 | 是 | 否 | 是 | 屡次执行查询,结果随数据库改变而改变 |
6 | 是 | 是 | 是 | 结果随数据库改变而改变 |
有此可见,Spring 设置的readOnly事务属性对oracle来讲是无效的。学习
底层实现原理是基于JDBC的相关属性设置,如:测试
(1)在JDBC中,指定只读事务的办法为: connection.setReadOnly(true)
;
(2)在Hibernate中,指定只读事务的办法为: session.setFlushMode(FlushMode.NEVER)
;
https://blog.csdn.net/msy_xingfu1314/article/details/50562991 当咱们查看 oracle 驱动官方文档时会发现有,其实 Oracle 数据库自己也是支持只读事务的,也就是只读模式,可是文档很明确的说明了只读模式只能经过oracle数据库自己进行设置:
Read-only connections are supported by the Oracle server, but not by the Oracle JDBC drivers.
For transactions, the Oracle server supports only the TRANSACTION_READ_COMMITTED and TRANSACTION_SERIALIZABLE transaction isolation levels. The default is TRANSACTION_READ_COMMITTED. Use the following methods of the oracle.jdbc.OracleConnection interface to get and set the level:
getTransactionIsolation: Gets this connection's current transaction isolation level.
setTransactionIsolation: Changes the transaction isolation level, using one of the TRANSACTION_* values.
对于使用jdbc驱动来讲,你只能设置TRANSACTION_READ_COMMITTED
和 TRANSACTION_SERIALIZABLE
两种隔离级别,若是你想要只读事务,只能经过执行SET TRANSACTION READ ONLY
完成。小编找了两篇更加全面的文章给你们参考
验证相关的数据库驱动能够在这里下载