让JPA支持Hibernate事务隔离级别配置

JPA本身不提供事务的隔离级别这个概念,所以如果直接配置如 isolation="READ_COMMITTED" 时,后台会报异常 

Standard JPA does not support custom isolation levels - use a special JpaDialect

如果想使用配置隔离级别需要自己写代码让jpa支持,代码里面用的是hibernate4。

public class HibernateJpaIsolationSupportDialect extends HibernateJpaDialect {
	private static final long serialVersionUID = 1L;
	
	private Logger logger = LoggerFactory
			.getLogger(HibernateJpaIsolationSupportDialect.class);

	@Override
	public Object beginTransaction(final EntityManager entityManager,
			final TransactionDefinition definition)
			throws PersistenceException, SQLException, TransactionException {
		if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
			getSession(entityManager).getTransaction().setTimeout(
					definition.getTimeout());
		}
		if (logger.isDebugEnabled()) {
			logger.debug(
					"Transaction Info: IsolationLevel={} , PropagationBehavior={} , Timeout={} , Name={}",
					new Object[] { definition.getIsolationLevel(),
							definition.getPropagationBehavior(),
							definition.getTimeout(), definition.getName()});
		}
		logger.debug("The isolation level set on the transaction is {}",
				definition.getIsolationLevel());
		ConnectionHandle connHandle = getJdbcConnection(entityManager, definition.isReadOnly());
		Connection conn = connHandle.getConnection();
		Integer previousIsolationLevel = DataSourceUtils
				.prepareConnectionForTransaction(conn, definition);
		logger.debug("The previousIsolationLevel {}", previousIsolationLevel);
		
		entityManager.getTransaction().begin();
		Object transactionData = prepareTransaction(entityManager,
				definition.isReadOnly(), definition.getName());

		return new IsolationSupportSessionTransactionData(transactionData,
				previousIsolationLevel, conn);
	}

	@Override
	public void cleanupTransaction(Object transactionData) {
		IsolationSupportSessionTransactionData isstd = (IsolationSupportSessionTransactionData) transactionData;
		super.cleanupTransaction(isstd.getSessionTransactionData());
		isstd.resetIsolationLevel();
	}

	private static class IsolationSupportSessionTransactionData {

		private final Object sessionTransactionData;
		private final Integer previousIsolationLevel;
		private final Connection connection;

		public IsolationSupportSessionTransactionData(
				Object sessionTransactionData,
				Integer previousIsolationLevel, Connection connection) {
			this.sessionTransactionData = sessionTransactionData;
			this.previousIsolationLevel = previousIsolationLevel;
			this.connection = connection;
		}

		public void resetIsolationLevel() {
			if (this.previousIsolationLevel != null) {
				DataSourceUtils.resetConnectionAfterTransaction(connection,
						previousIsolationLevel);
			}
		}

		public Object getSessionTransactionData() {
			return this.sessionTransactionData;
		}

	}

}

然后事务配置里面使用我们自己写的HibernateJpaIsolationSupportDialect。

<!-- transactionManager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="framework.support.hibernate.HibernateJpaIsolationSupportDialect" />
</property>
</bean>

,另外entityManagerFactory里面的jpaVendorAdapter,不要使用否则HibernateJpaIsolationSupportDialect不起作用。

<!-- <property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false"/>
<property name="database" value="MYSQL"/>
</bean>
</property> -->

关于这个问题的讨论帖: http://stackoverflow.com/questions/5234240/hibernatespringjpaisolation-does-not-work

转载于:https://my.oschina.net/yybear/blog/101256

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值