当前位置: 首页 > 知识库问答 >
问题:

Spring@transactional不会导致回滚

罗渝
2023-03-14

在我开始这看似很长的一段之前,我想对我可能收到的任何建议/建议表示感谢。朱约翰

我开发了一个简单的测试来帮助我理解spring的声明性(@Transactional)事务管理框架如何与spring的RESTful web服务结合使用。

为此,我开发了以下RESTful控制器:

    @RequestMapping(value="register", method=RequestMethod.POST, produces="application/json", consumes="application/json")
public void accountFacade () {
    tester.accountTest();
}

其中,“tester”是以下服务类的bean,并自动连接到此控制器。类中唯一的方法是事务性的:

@Transactional
public class TransactionTest extends ActivityStatus {
@Autowired
private ObjectManager objectManager;

@Autowired
private GenericDB gdb;

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("META-INF/test- context.xml");   
    TransactionTest tester = (TransactionTest) ac.getBean("tester");
    tester.accountTest();
}

@Transactional(readOnly=false, propagation=Propagation.REQUIRED, isolation=Isolation.READ_COMMITTED,
               rollbackFor=RuntimeException.class)
public void accountTest () {
    try {
           String sql = "insert into account set account_id=0, ....";
           gdb.jdbcTemplateInsert(sql);
        
           sql = "insert into login set account_id=....";
           gdb.jdbcTemplateInsert(sql, values);
    } catch (DataAccessException dae) {
        System.out.println("Catching DataAccessException (dae)");
        throw new RuntimeException (dae);
    }
}

在上面,GenericDB是一个提供定制jdbcTemplate的类。

为了触发回滚,我故意设置数据,使第一个SQL成功,第二个失败。

问题:最终结果是一个记录被插入到帐户中,并保持不变,即使第二次插入也按预期失败。

几点注意事项

>

  • 如果我向两个SQL提供正确的数据,测试运行将成功。

    如果我只是从Eclipse作为独立java应用程序运行TransactionTest(请参阅main(…)在针对本地数据库的类defn中,似乎发生了回滚。

    执行确实捕获了AccessDataException(请参阅“catch”块中的打印语句)。因此,我断定抛出了“new RuntimeException()”。

    由于插入失败而产生的错误消息(调用堆栈)确实显示了以下内容:

    在org。springframework。交易拦截器。交易接收器。invoke(TransactionInterceptor.java:110)[spring-tx-3.1.1.RELEASE.jar:3.1.1.RELEASE]

    这表明方法“帐户测试”被Spring的事务拦截器正确“包装”。这似乎暗示我的配置(见下文)是有效的。

    应用中的相关行Context.xml:

    <tx:annotation-driven transaction-manager="txManager" />
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="tester" class="org.SandRiver.Controllers.TransactionTest">
    </bean>
    

    关于我的执行环境的几句话:我在OpenShift的环境中运行了应用程序,该环境包括

    1. jboss 6.1
    2. mysql 5。x(我不知道“x”)
    3. 我使用Maven来更新Spring版本
  • 共有1个答案

    韶兴德
    2023-03-14

    您需要使用InnoDB而不是MyISAM来支持事务。

    要检查表的存储引擎:

    mysql> show create table your_tbl_name;
    

    要使用InnoDB创建表,请执行以下操作:

    CREATE TABLE your_tbl_name (
      col1 VARCHAR(10),
      col2 VARCHAR(10)
    )
    ENGINE = InnoDB;
    

    希望这有帮助。

     类似资料:
    • 我使用的是Spring Boot应用程序,在上面我试图实现事务性管理。但是Spring不会回滚用相同方法保存的数据。 代码库:https://github.com/vinothr/spring-boot-transactional-example

    • Spring 4.1.4 Hibernate 4.2.0 JDK 1.8 我的上下文:我有一个控制器调用-->Service-->调用Dao业务功能是删除(在1到许多DB关系中)一些子级,但不是所有子级。然后,在删除了一些子项之后,我尝试删除父项,然后我得到了java.sql.SqlIntegrityConstraintViolationException

    • 问题内容: 我正在尝试实现一个简单的DAO。我有道: 和一个实体: 这是appContext.xml: 除非我在之后调用或插入未执行。这是为什么?如果删除,则刷新时会出现“没有正在进行的事务”的错误,但是如果删除刷新,则不会插入到数据库中。 问题答案: 之所以这样工作是因为您使用标记了事务为只读。 如您所见,由于您仍然可以通过手动调用保留更改,因此它不会使您的事务实际上是只读的。但是,它在事务结束

    • @Transactional标记是最近添加的。所以不确定它是否像预期的那样工作。 代码: 服务类别:

    • 我使用@Transactional与Spring引导和jpa。但它不起作用。有人能帮忙吗? 我的插件在myDAO中,它是在服务类中自动生成的。下面的代码是实现服务接口的服务类的方法

    • 我之前有一个关于这个问题的帖子已经解决了。然而,自从用自动连线bean和较少的XML配置重建项目后,我发现我正在重新考虑这个问题。我遵循了我以前的项目实现这一点的方式,但它不起作用。有人能帮助我为什么或者我应该改变什么来使它工作吗? 注册服务: 注册DAO: