gpt4 book ai didi

java - Spring全局事务在获取元素后提交

转载 作者:行者123 更新时间:2023-12-01 15:49:03 26 4
gpt4 key购买 nike

我正在使用 Spring 和 Hibernate 以及 Jta Transactions,我有 2 个数据库,并且我在事务方法中遇到问题。

在这个方法中,我插入了很多对象,但抛出了一个异常来回滚插入,这里的代码按我的预期工作,因为对象没有出现在数据库中。

但是如果我在获取同一个表的对象的方法中添加一行,这些对象就会被提交到数据库中。

我认为当我进行 SELECT 时,对象会自动提交,因为异常会再次抛出,并且对象会保留到数据库中。

我的 xml 和代码:

dao.xml

<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:configuracion_dao.properties" />
</bean>

<bean name="productosDAO" class="practica1.hibernate.HibernateProductosDAOImpl"
parent="abstractPracticaBean">
<property name="sessionFactory" ref="hibernateSessionFactory" />
</bean>

<bean name="tercerosDAO" class="${tercerosDAO.classname}" parent="abstractPracticaBean">
<property name="dataSource" ref="dataSourceDatos" />
</bean>

<bean name="auditoriaDAO" class="practica1.hibernate.HibernateAuditoriaDAOImpl" parent="abstractPracticaBean">
<property name="sessionFactory" ref="hibernateSessionFactory2" />
</bean>


<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceDatos" />
<property name="mappingResources">
<list>
<value>hibernate-mappings.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>

<bean id="hibernateSessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceAuditoria" />
<property name="mappingResources">
<list>
<value>hibernate-mappings-auditoria.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>


<bean name="dataSourceDatos" class="org.enhydra.jdbc.standard.StandardXADataSource">
<property name="driverName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:/tmp/datos.db;create=true" />
<property name="transactionManager" value="#{txManager.transactionManager}" />
</bean>

<jdbc:initialize-database data-source="dataSourceDatos"
ignore-failures="ALL">
<jdbc:script location="classpath:practica1/sql/creacion_derby.sql" />
<jdbc:script location="classpath:practica1/sql/datos.sql" />
</jdbc:initialize-database>

<bean name="dataSourceAuditoria" class="org.enhydra.jdbc.standard.StandardXADataSource">
<property name="driverName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:/tmp/auditoria.db;create=true" />
<property name="transactionManager" value="#{txManager.transactionManager}" />
</bean>

<jdbc:initialize-database data-source="dataSourceAuditoria"
ignore-failures="ALL">
<jdbc:script location="classpath:practica1/sql/creacion_auditoria_derby.sql" />
</jdbc:initialize-database>

<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" value="#{jotm.transactionManager}" />
<property name="userTransaction" value="#{jotm.userTransaction}" />
</bean>

<bean id="jotm" class="org.objectweb.jotm.Jotm" destroy-method="stop">
<constructor-arg value="true" />
<constructor-arg value="false" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />

bo.xml

<bean name="tercerosBO" class="practica1.impl.TercerosBOImpl"
parent="abstractPracticaBean" autowire="constructor">

</bean>
<bean name="productosBO" class="practica1.impl.ProductosBOImpl"
parent="abstractPracticaBean">
<property name="productosDAO" ref="productosDAO" />
<property name="auditoriaDAO" ref="auditoriaDAO" />
</bean>

应用程序.xml

<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="mensajes" />
</bean>

<bean id="abstractPracticaBean" class="practica1.impl.AbstractPracticaBean" abstract="true">
<property name="messageSource" ref="messageSource"></property>
</bean>

<import resource="bo.xml" />
<import resource="dao.xml" />

交易方式:

@Transactional
@Override
public void actualizaPrecio(double porcentaje) {
internalActualizaPrecio(porcentaje);
}
private void internalActualizaPrecio(double porcentaje) {
auditoriaDAO.insertAuditoria(getMessageSource().getMessage(
"mensaje.actualizar_productos", new Object[] { porcentaje },
null));
int i = 0;
auditoriaDAO.getAuditorias(); // Without this line its works like I expected
List<Producto> productos = productosDAO.getProductos();
for (Producto producto : productos) {
i++;
if (i > 3)
throw new UnsupportedOperationException(
"Error para que veamos las transacciones");
producto.setPrecio(producto.getPrecio().multiply(
new BigDecimal(porcentaje).divide(new BigDecimal(100))));
productosDAO.updateProducto(producto);
}
}

我意识到,如果我使用auditeriaDAO.getAuditorias(),回滚只会影响Producto,但如果我使用productoDAO.getProductos(),回滚只会影响Auditoria...

最佳答案

您可能会在这里混淆flushcommit:SELECT语句通常会刷新所有先前的SQL语句,以便获取最新的数据(关于您之前在 tx 中所做的更改)。有可能在这样的 SELECT 语句完成之前(如果我没记错的话,下面的 DAO 调用是对 2nd sessionFactory 进行的),异常退出该方法时没有 flush。因此无需修改数据库。

所以问题是:你确定你正在有效地回滚交易吗?我看到您注释了一个 private 方法:Spring AOP 基于代理的机制无法处理该方法!由于这种基于代理的机制,您必须注释 public 方法并从注释方法的类外部调用它。请参阅 documentation 中的“方法可见性和 @Transactional” block .

另一个线索:你有 2 个 sessionFactories,所以我假设你正在使用 XA 事务/数据源:你确定这部分的配置没问题吗?

关于java - Spring全局事务在获取元素后提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6504311/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com