Hibernate 监听器 + 事务信息
Hibernate listeners + transaction info
在我的 Spring Boot Data/JPA/Hibernate 项目中,我配置了以下 CREATE、UPDATE 和 DELETE 侦听器:
@Component
public class HibernateListenersConfigurer {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private HibernateEntityListener listener;
@PostConstruct
public void registerListeners() {
final HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) this.entityManagerFactory;
final SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
final EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);
registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(listener);
registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(listener);
}
}
@Component
public class HibernateEntityListener implements PostCommitInsertEventListener, PostCommitUpdateEventListener, PostCommitDeleteEventListener {
@Override
public boolean requiresPostCommitHanding(EntityPersister persister) {
return true;
}
@Override
public void onPostInsert(PostInsertEvent event) {
//get transaction information(like ID) here
}
...
}
在我的侦听器方法中,如 onPostInsert
、onPostUpdate
等,我需要获取交易信息(如交易 ID)。
怎么做?
为了获取交易详情,请使用以下代码,其中事件可能属于 PostInsertEvent
或 PostUpdateEvent
session = event.getPersister().getFactory().getCurrentSession();
Transaction transaction = session.getTransaction();
事务 ID 是特定于数据库的。
使用 PostgreSQL,您可以简单地 运行 这个本机查询来获取当前事务 ID:
Number transactionId = (Number) session
.createSQLQuery("select txid_current()")
.uniqueResult();
对于MySQL,您需要运行 5.7 或更高版本:
Number transactionId = (Number) session
.createSQLQuery(
"SELECT GTID " +
"FROM events_transactions_current e " +
"JOIN performance_schema.threads t ON e.THREAD_ID = t.THREAD_ID " +
"WHERE t.PROCESSLIST_ID = CONNECTION_ID()")
.uniqueResult();
或 MySQL 5.5:
Number transactionId = (Number) session
.createSQLQuery(
"SELECT trx_id " +
"FROM information_schema.innodb_trx " +
"WHERE trx_mysql_thread_id = CONNECTION_ID()")
.uniqueResult();
在我的 Spring Boot Data/JPA/Hibernate 项目中,我配置了以下 CREATE、UPDATE 和 DELETE 侦听器:
@Component
public class HibernateListenersConfigurer {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private HibernateEntityListener listener;
@PostConstruct
public void registerListeners() {
final HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) this.entityManagerFactory;
final SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
final EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);
registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(listener);
registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(listener);
}
}
@Component
public class HibernateEntityListener implements PostCommitInsertEventListener, PostCommitUpdateEventListener, PostCommitDeleteEventListener {
@Override
public boolean requiresPostCommitHanding(EntityPersister persister) {
return true;
}
@Override
public void onPostInsert(PostInsertEvent event) {
//get transaction information(like ID) here
}
...
}
在我的侦听器方法中,如 onPostInsert
、onPostUpdate
等,我需要获取交易信息(如交易 ID)。
怎么做?
为了获取交易详情,请使用以下代码,其中事件可能属于 PostInsertEvent
或 PostUpdateEvent
session = event.getPersister().getFactory().getCurrentSession();
Transaction transaction = session.getTransaction();
事务 ID 是特定于数据库的。
使用 PostgreSQL,您可以简单地 运行 这个本机查询来获取当前事务 ID:
Number transactionId = (Number) session
.createSQLQuery("select txid_current()")
.uniqueResult();
对于MySQL,您需要运行 5.7 或更高版本:
Number transactionId = (Number) session
.createSQLQuery(
"SELECT GTID " +
"FROM events_transactions_current e " +
"JOIN performance_schema.threads t ON e.THREAD_ID = t.THREAD_ID " +
"WHERE t.PROCESSLIST_ID = CONNECTION_ID()")
.uniqueResult();
或 MySQL 5.5:
Number transactionId = (Number) session
.createSQLQuery(
"SELECT trx_id " +
"FROM information_schema.innodb_trx " +
"WHERE trx_mysql_thread_id = CONNECTION_ID()")
.uniqueResult();