标签: spring-transactions

@Transactional方法在没有@Transactional anotation的情况下调用另一个方法?

我在Service类中看到了一个被标记为的方法@Transactional,但它也在同一个类中调用了一些未标记为的其他方法@Transactional.

这是否意味着对单独方法的调用导致应用程序打开与DB的单独连接或挂起父事务等?

没有任何注释的方法的默认行为是什么,由另一个带@Transactional注释的方法调用?

java spring transactional spring-transactions

67
推荐指数
4
解决办法
6万
查看次数

Spring - 是否可以在同一个应用程序中使用多个事务管理器?

我是Spring的新手,我想知道是否可以在同一个应用程序中使用多个事务管理器?

我有两个数据访问层 - 一个用于两个数据库.我想知道,你如何为一层使用一个事务管理器而另一层使用不同的事务管理器.我不需要跨两个数据库执行事务.但我确实需要单独对每个数据库执行事务.我创建了一个图像来帮助概述我的问题:

替代文字

这是我的应用程序上下文配置:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:component-scan base-package="cheetah.repositories" />
    <tx:annotation-driven />

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="accounts" />
    </bean>

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>
Run Code Online (Sandbox Code Playgroud)

以下是使用此配置的示例:

@Repository
public class JpaAccountRepository implements AccountRepository {

    @PersistenceContext(unitName = "cheetahAccounts")
    private EntityManager accountManager;

    @Override
    @Transactional
    public Account findById(long id) {

        Account account = accountManager.find(Account.class, id);
        return account;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,对于帐户存储库,我想使用实体管理器工厂,并将持久性单元设置为帐户.但是,使用我的BusinessData Repository,我想使用具有不同持久性单元的实体管理器工厂.由于我只能定义一个事务管理器bean,我如何为不同的存储库使用不同的事务管理器?

谢谢你的帮助.

java spring jpa transactionmanager spring-transactions

62
推荐指数
2
解决办法
6万
查看次数

在类和方法上定义@Transactional之间有什么区别

情况1

@Transactional
public class UserServiceImpl implements UserService {

    ...................
    public void method1(){
        try{
            method2();
        }catch(Exception e){

        }
    }
    public void method2(){

    }
}
Run Code Online (Sandbox Code Playgroud)

案例2

public class UserServiceImpl implements UserService {

    ...................
    public void method1(){
        try{
            method2();
        }catch(Exception e){

        }
    }
    @Transactional
    public void method2(){

    }
}
Run Code Online (Sandbox Code Playgroud)

在case1中,如果发生任何异常,则回滚正在工作,但在情况2中它不起作用.如果我遵循case1,是否存在任何性能问题?

java spring spring-mvc spring-transactions

57
推荐指数
4
解决办法
4万
查看次数

如何在@Transactional方法中手动强制提交?

我正在使用Spring/Spring-data-JPA,并发现自己需要在单元测试中手动强制提交.我的用例是我正在进行多线程测试,其中我必须使用在生成线程之前持久化的数据.

不幸的是,鉴于测试在一个@Transactional事务中运行,即使是一个flush也没有让它可以被生成的线程访问.

   @Transactional   
   public void testAddAttachment() throws Exception{
        final Contract c1 = contractDOD.getNewTransientContract(15);
        contractRepository.save(c1);

        // Need to commit the saveContract here, but don't know how!                
        em.getTransaction().commit();

        List<Thread> threads = new ArrayList<>();
        for( int i = 0; i < 5; i++){
            final int threadNumber = i; 
            Thread t =  new Thread( new Runnable() {
                @Override
                @Transactional
                public void run() {
                    try {
                        // do stuff here with c1

                        // sleep to ensure that the thread is not …
Run Code Online (Sandbox Code Playgroud)

java spring jpa spring-transactions spring-data

52
推荐指数
3
解决办法
9万
查看次数

Spring事务REQUIRED与REQUIRES_NEW:回滚事务

我有一个具有propagation = Propagation.REQUIRES_NEW事务属性的方法:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(final UserBean userBean) {
    //Some logic here that requires modification in DB
}
Run Code Online (Sandbox Code Playgroud)

此方法可以同时调用多次,并且对于每个事务,如果发生错误而不是回滚(独立于其他事务).

问题是,这可能会迫使Spring创建多个事务,即使另一个事务可用,也可能导致一些性能问题.


Java doc propagation = Propagation.REQUIRED说:Support a current transaction, create a new one if none exists.

这似乎解决了性能问题,不是吗?

回滚问题怎么样?如果新方法调用在使用现有事务时回滚,该怎么办?即使以前的电话会不会回滚整个交易?

[编辑] 我想我的问题不够明确:

我们有数百个客户端连接到我们的服务器.

对于每个客户端,我们自然需要发送有关事务的反馈(OK或exception - > rollback).

我的问题是:如果我使用REQUIRED,是否意味着只使用了一个事务,如果第100个客户端遇到问题,第一个客户端的事务也会回滚?

java spring hibernate transactions spring-transactions

49
推荐指数
2
解决办法
11万
查看次数

匹配的通配符是严格的,但是找不到元素'tx:annotation-driven'的声明

我正在尝试配置JSF + Spring + hibernate,我想要运行测试,但是当我在application-context.xml文件中使用"tx:annotation-driven"时,我收到此错误:

匹配的通配符是严格的,但是找不到元素'tx:annotation-driven'的声明

这是我的application-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"

       xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-2.5.6.xsd
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-2.5.6.xsd
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-2.5.6.xsd
" xmlns:tool="http://www.springframework.org/schema/tool">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@192.168.56.101:1521:Gpsi"/>
        <property name="username" value="omar"/>
        <property name="password" value="omar"/>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
       <property name="dataSource" ref="dataSource"/>
       <property name="annotatedClasses">
            <list>
                <value>om.mycompany.model.Course</value>
                <value>om.mycompany.model.Student</value>
                <value>om.mycompany.model.Teacher</value>
            </list>
       </property>
       <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
            </props>
       </property>

    </bean>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
       <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <tx:annotation-driven transaction.manager="transactionManager"/>

    <context:annotation-config/>
    <context:component-scan base.package="com.mmycompany"/>
</beans>
Run Code Online (Sandbox Code Playgroud)

这是我的CourseServiceImplTest.我还没有实现测试:

public class …
Run Code Online (Sandbox Code Playgroud)

spring transactions spring-transactions

42
推荐指数
3
解决办法
13万
查看次数

为什么spring/hibernate只读数据库事务比读写运行慢?

我一直在研究只读与读写数据库事务的性能.MySQL服务器是远程的,因此我很容易看到不同事务类型之间的差异.这是连接池,我知道它基于比较第一次和第二次JDBC调用.

当我将Spring AOP配置为在我的DAO调用上使用只读事务时,与读写相比,调用速度慢 30-40%:

<!-- slower -->
<tx:method name="find*" read-only="true" propagation="REQUIRED" />
...
// slower
@Transaction(readOnly = true)
Run Code Online (Sandbox Code Playgroud)

要么

<!-- faster -->
<tx:method name="find*" read-only="false" propagation="REQUIRED" />
...
// faster
@Transaction
Run Code Online (Sandbox Code Playgroud)

与:

<!-- slower -->
<tx:method name="find*" read-only="true" propagation="REQUIRED" />
...
// slower
@Transaction(readOnly = true)
Run Code Online (Sandbox Code Playgroud)

要么

<!-- faster -->
<tx:method name="find*" read-only="false" propagation="REQUIRED" />
...
// faster
@Transaction
Run Code Online (Sandbox Code Playgroud)

看看tcpdump,似乎只读事务在与MySQL交谈时做得更多.这是只读转储读写.

  1. 任何人都可以解释为什么只读通话需要更长的时间.这是预期的吗?

  2. 除了改善网络之外,还有什么我做错了或能做些什么来提高速度?刚刚发现了这篇很棒的帖子并提供了一些很好的性能建议.还有其他意见吗?

非常感谢.

java spring hibernate database-performance spring-transactions

28
推荐指数
1
解决办法
9023
查看次数

Spring嵌套事务

在我的Spring Boot项目中,我实现了以下服务方法:

@Transactional
public boolean validateBoard(Board board) {
    boolean result = false;
    if (inProgress(board)) {
        if (!canPlayWithCurrentBoard(board)) {
            update(board, new Date(), Board.AFK);
            throw new InvalidStateException(ErrorMessage.BOARD_TIMEOUT_REACHED);
        }
        if (!canSelectCards(board)) {
            update(board, new Date(), Board.COMPLETED);
            throw new InvalidStateException(ErrorMessage.ALL_BOARD_CARDS_ALREADY_SELECTED);
        }
        result = true;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

在这个方法里面,我使用另一种叫做的服务方法update:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public Board update(Board board, Date finishedDate, Integer status) {
    board.setStatus(status);
    board.setFinishedDate(finishedDate);

    return boardRepository.save(board);
}
Run Code Online (Sandbox Code Playgroud)

我需要update独立于validateBoard方法中启动的所有者事务,在方法中提交对数据库的更改.现在任何变化都会在任何异常的情况下回滚.

即使@Transactional(propagation = Propagation.REQUIRES_NEW)它不起作用.

如何使用Spring正确执行此操作并允许嵌套事务?

spring spring-transactions spring-data spring-data-jpa spring-boot

24
推荐指数
4
解决办法
2万
查看次数

Spring @Transactional无法正常工作

我之前有一个关于这个问题的帖子已经解决了.但是,自从使用自动连线bean和较少的XML配置重建项目后,我发现我正在重新审视此问题.我已按照我之前的项目实施此方式的方式,但它不起作用.有人可以帮助我解决为什么或我应该改变什么来使它工作?

我故意在插入用户详细信息方法中使用不存在的表名来故意抛出异常.但是,不会回滚插入用户和插入用户角色的语句.请帮忙.


我目前的注册设计是这样的.

部分servlet.xml中:

<context:component-scan base-package="com.doyleisgod.golfer.controllers"/>
<context:component-scan base-package="com.doyleisgod.golfer.dao"/>
<context:component-scan base-package="com.doyleisgod.golfer.services"/>
<context:component-scan base-package="com.doyleisgod.golfer.validators"/>
Run Code Online (Sandbox Code Playgroud)


部分应用程序上下文:

<context:annotation-config />
<tx:annotation-driven />    

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
Run Code Online (Sandbox Code Playgroud)


注册控制器:

package com.doyleisgod.golfer.controllers;

import javax.validation.Valid;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.doyleisgod.golfer.formdata.RegistrationForm;
import com.doyleisgod.golfer.services.IRegistrationService;
import com.doyleisgod.golfer.validators.RegistrationFormValidator;

/**
 * …
Run Code Online (Sandbox Code Playgroud)

spring spring-mvc transactional spring-transactions

23
推荐指数
1
解决办法
5万
查看次数

如何在spring jdbc模板中将autocommit设置为false

目前我通过向数据源bean id添加属性来在spring中将autocommit设置为false,如下所示:

   <property name="defaultAutoCommit" value="false" /> 
Run Code Online (Sandbox Code Playgroud)

但是我需要在执行我的程序之前在一个java方法中专门添加它.我使用了下面的代码片段.

  getJdbcTemplate().getDataSource().getConnection().setAutoCommit(false);
Run Code Online (Sandbox Code Playgroud)

但上面的一行并没有将autocommit设置为false?
我错过了什么吗?
或者通过spring在特定java方法中设置autocommit的任何替代方法

谢谢

spring spring-mvc spring-jdbc spring-transactions

22
推荐指数
5
解决办法
3万
查看次数