spring只读事务怎么回事

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/buyaore_wo/article/details/82388136

如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;

如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。

对于只读查询,可以指定事务类型为readonly,即只读事务。由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。

在JDBC中,指定只读事务的办法为:

connection.setReadOnly(true);

spring中

 注解方式:   @Transactional(readOnly=true)

xml aop配置方式:

	<tx:advice id="transaction"
		transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*_tx_r" propagation="REQUIRED"
				read-only="true" />
			<tx:method name="*_tx_s" propagation="SUPPORTS" />
			<tx:method name="*" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>

我们来看一下spring中方法执行过程中事务处理

从事务处理过程中可以看到spring对数据库连接进行了只读设置

(以下红色部分为在设置数据库连接为read-only)

Creating new transaction with name [com.yj.tr.test.spring.tx.biz.TxApiImpl.txMethod2_tx_r]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
opened session at timestamp: 6291673123250176 --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl
Opened new Session [org.hibernate.impl.SessionImpl@6e8c94f3] for Hibernate transaction --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.HibernateTransactionManager
Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@6e8c94f3] --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.HibernateTransactionManager
opening JDBC connection --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.ConnectionManager
trace com.mchange.v2.resourcepool.BasicResourcePool@4baed682 [managed: 50, unused: 49, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@20e4181c) --[DEBUG] 2018-09-04 17:23:28-com.mchange.v2.resourcepool.BasicResourcePool
Setting JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@5ad4df4e] read-only --[DEBUG] 2018-09-04 17:23:28-org.springframework.jdbc.datasource.DataSourceUtils
setting flush mode to: MANUAL --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl
begin --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
current autocommit status: true --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
disabling autocommit --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
after transaction begin --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.JDBCContext
Exposing Hibernate transaction as JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@5ad4df4e] --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.HibernateTransactionManager
Bound value [org.springframework.jdbc.datasource.ConnectionHolder@54ab2f99] for key [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 20, acquireRetryAttempts -> 10, acquireRetryDelay -> 2000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 3000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge0yg9x19h2sok1hv62zg|4c5474f5, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge0yg9x19h2sok1hv62zg|4c5474f5, idleConnectionTestPeriod -> 60, initialPoolSize -> 50, jdbcUrl -> jdbc:mysql://192.168.0.20:15024/gds_qa?setUnicode=true&characterEncoding=utf8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 300, maxPoolSize -> 800, maxStatements -> 300, maxStatementsPerConnection -> 200, minPoolSize -> 50, numHelperThreads -> 30, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]] to thread [RMI TCP Connection(2)-192.168.0.88] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Bound value [org.springframework.orm.hibernate3.SessionHolder@36873316] for key [org.hibernate.impl.SessionFactoryImpl@3bdd1413] to thread [RMI TCP Connection(2)-192.168.0.88] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Initializing transaction synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Getting transaction for [com.yj.tr.test.spring.tx.biz.TxApiImpl.txMethod2_tx_r] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.interceptor.TransactionAspectSupport
txMethod2_tx_r
Completing transaction for [com.yj.tr.test.spring.tx.biz.TxApiImpl.txMethod2_tx_r] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.interceptor.TransactionAspectSupport
Triggering beforeCommit synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
Triggering beforeCompletion synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
Initiating transaction commit --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@6e8c94f3] --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.HibernateTransactionManager
commit --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
before transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.JDBCContext
before transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl
re-enabling autocommit --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
committed JDBC Connection --[DEBUG] 2018-09-04 17:23:28-org.hibernate.transaction.JDBCTransaction
after transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.JDBCContext
transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources! --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.ConnectionManager
after transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl
Triggering afterCommit synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
Triggering afterCompletion synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.AbstractPlatformTransactionManager
Clearing transaction synchronization --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Removed value [org.springframework.orm.hibernate3.SessionHolder@36873316] for key [org.hibernate.impl.SessionFactoryImpl@3bdd1413] from thread [RMI TCP Connection(2)-192.168.0.88] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Removed value [org.springframework.jdbc.datasource.ConnectionHolder@54ab2f99] for key [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 20, acquireRetryAttempts -> 10, acquireRetryDelay -> 2000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 3000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge0yg9x19h2sok1hv62zg|4c5474f5, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge0yg9x19h2sok1hv62zg|4c5474f5, idleConnectionTestPeriod -> 60, initialPoolSize -> 50, jdbcUrl -> jdbc:mysql://192.168.0.20:15024/gds_qa?setUnicode=true&characterEncoding=utf8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 300, maxPoolSize -> 800, maxStatements -> 300, maxStatementsPerConnection -> 200, minPoolSize -> 50, numHelperThreads -> 30, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]] from thread [RMI TCP Connection(2)-192.168.0.88] --[DEBUG] 2018-09-04 17:23:28-org.springframework.transaction.support.TransactionSynchronizationManager
Resetting read-only flag of JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@5ad4df4e] --[DEBUG] 2018-09-04 17:23:28-org.springframework.jdbc.datasource.DataSourceUtils
Closing Hibernate Session [org.hibernate.impl.SessionImpl@6e8c94f3] after transaction --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.HibernateTransactionManager
Closing Hibernate Session --[DEBUG] 2018-09-04 17:23:28-org.springframework.orm.hibernate3.SessionFactoryUtils
closing session --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl
performing cleanup --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.ConnectionManager
releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)] --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.ConnectionManager
checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 --[DEBUG] 2018-09-04 17:23:28-com.mchange.v2.c3p0.stmt.GooGooStatementCache
com.mchange.v2.async.ThreadPoolAsynchronousRunner@1ee47d9e: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@a462cda --[DEBUG] 2018-09-04 17:23:28-com.mchange.v2.async.ThreadPoolAsynchronousRunner
trace com.mchange.v2.resourcepool.BasicResourcePool@4baed682 [managed: 50, unused: 49, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@20e4181c) --[DEBUG] 2018-09-04 17:23:28-com.mchange.v2.resourcepool.BasicResourcePool
after transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.JDBCContext
checkinAll(): com.mchange.v2.c3p0.stmt.DoubleMaxStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0 --[DEBUG] 2018-09-04 17:23:28-com.mchange.v2.c3p0.stmt.GooGooStatementCache
transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources! --[DEBUG] 2018-09-04 17:23:28-org.hibernate.jdbc.ConnectionManager
after transaction completion --[DEBUG] 2018-09-04 17:23:28-org.hibernate.impl.SessionImpl

猜你喜欢

转载自blog.csdn.net/buyaore_wo/article/details/82388136