从Thread启动的Spring事务未开始

时间:2015-09-27 04:14:35

标签: java multithreading spring concurrency eclipselink

我正在测试这种情况,当我从Thread调用委托方法时,spring transaction不会开始。 但是,当我直接调用委托方法时,它完美地工作。任何人都可以建议这里缺少什么..?

这是我的主要课程:

@Component
public class SpringMainApplication {

    @Autowired
    private InsertThread insertThread;
    @Autowired
    private PrintThread printThread;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;


    public void startApplication() {
        taskExecutor.execute(insertThread);
        taskExecutor.execute(printThread);

    /*This works
    int count =1; 
    while(count<=4) {
        count ++;
        Employee empBean = new Employee();
        empBean.setAddress("ADD");
        empBean.setName("NAME");
        empDelegate.insertElement(empBean );
    }*/
        }
}

我的线程类:插入线程并打印线程以插入元素并从DB中检索元素。我在这里使用MYSQL

package com.sap.springconcurrent.thread;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sap.springconcurrent.bean.Employee;
import com.sap.springconcurrent.bean.TestBean;
import com.sap.springconcurrent.delegate.EmployeeDelegate;

@Service
public abstract class InsertThread extends Thread{

    @Autowired
    EmployeeDelegate empDelegate;

    public InsertThread(EmployeeDelegate empDelegate) {
        this.empDelegate = empDelegate;
    }

    @Override
    public void run() {
        System.out.println("Count"+ empDelegate.getCount());
        while(empDelegate.getCount() <= 5){
            synchronized (empDelegate) {
                Employee emp = new Employee();
                emp.setName(createTestBean().getTestValue());
                emp.setAddress("Address");
                System.out.println("Insert"+ empDelegate.getCount() +1 );
                empDelegate.insertElement(emp);
            }
        }
    }

    protected abstract TestBean createTestBean();

}

package com.sap.springconcurrent.thread;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.sap.springconcurrent.bean.TestBean;
import com.sap.springconcurrent.delegate.EmployeeDelegate;

@Service
@Scope("singleton")
public class PrintThread extends Thread {

    @Autowired
    TestBean testBean;
    @Autowired
    EmployeeDelegate empDelegate;

    public PrintThread(EmployeeDelegate empDelegate) {
        this.empDelegate = empDelegate;
    }

    @Override
    public void run() {
        while (empDelegate.getCount() <= 10) {
            synchronized (empDelegate) {
                empDelegate.retrieveElement(testBean.getTestValue());
            }
        }
    }
}

我的bean来自这里我称之为处理交易的DAO

package com.sap.springconcurrent.delegate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.sap.springconcurrent.bean.Employee;
import com.sap.springconcurrent.dao.EmployeeDao;

@Service
@Scope("singleton")
public class EmployeeDelegate {

    @Autowired
    EmployeeDao doa;

    private boolean elementRetreived = true;
    private int count = 0;

    public void insertElement(Employee empBean) {
        System.out.println("Insert Start");
        while (!elementRetreived) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count++;
        empBean.setName(empBean.getName() + count);
        empBean.setAddress(empBean.getAddress() + count);
        System.out.println("Calling DAo");
        Employee emp = saveEmp(empBean);
        System.out.println("Inserted Employee" + emp.toString());
        elementRetreived = false;
        notifyAll();
    }
    //@Transactional(propagation=Propagation.REQUIRED)
    public Employee saveEmp(Employee empBean) {
        return doa.save(empBean);
    }

    public void retrieveElement(String name) {
        while (elementRetreived) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Employee emp = doa.getEmployeeWithName(name + count);
        System.out.println("Retrieved Employee" + emp.toString());
        elementRetreived = true;
        notifyAll();
    }

    public boolean isElementRetreived() {
        return elementRetreived;
    }

    public int getCount() {
        return count;
    }

}

我的道: 这是交易制作

package com.sap.springconcurrent.dao;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sap.springconcurrent.bean.Employee;

@Repository
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class EmployeeDao {

    @PersistenceContext
    EntityManager entityManagerFactory;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Employee save(Employee employee) {
        System.out.println("Insertint");
        entityManagerFactory.persist(employee);
        return employee;
    }

    @Transactional(readOnly=true)
    public Employee getEmployeeWithName(String empName) {
        String query = "select emp from Employee emp where emp.name LIKE :name ";
        Query q = entityManagerFactory.createQuery(query);
        q.setParameter("name", empName);
        return (Employee) q.getResultList().get(0);
    }

}

Spring COnfig :

<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.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.sap.springconcurrent" />
    <tx:annotation-driven transaction-manager="transactionManager" />
    <bean id="testBean" class="com.sap.springconcurrent.bean.TestBean"
        scope="prototype">
        <property name="testValue" value="testValue"></property>
    </bean>
    <bean class="org.springframework.orm.jpa.JpaTransactionManager"
        id="transactionManager" scope="prototype">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean id="empDelegate" class="com.sap.springconcurrent.delegate.EmployeeDelegate">

    </bean>

    <bean id="insertThread" class="com.sap.springconcurrent.thread.InsertThread"
        scope="prototype">
        <constructor-arg ref="empDelegate" />
        <lookup-method name="createTestBean" bean="testBean" />
    </bean>

    <bean id="printThread" class="com.sap.springconcurrent.thread.PrintThread"
        scope="prototype">
        <constructor-arg ref="empDelegate" />
    </bean>

    <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    </bean>

    <bean name="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/mytestdb" />
        <property name="username" value="root" />
        <property name="password" value="saplab" />
    </bean>

    <bean id='entityManagerFactory'
        class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'>
        <property name="persistenceUnitName" value="testPersistenceUnit" />
        <property name="packagesToScan" value="com.sap.springconcurrent.bean.Employee" />
        <property name='dataSource' ref='dataSource' />
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform"
                    value="org.eclipse.persistence.platform.database.MySQLPlatform" />
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />

        </property>
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.weaving" value="false" />
            </map>
        </property>
    </bean>

</beans>

persistence Xml :

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="driftsloggPersistenceUnit" transaction-type="RESOURCE_LOCAL">
         <provider>
            org.eclipse.persistence.jpa.PersistenceProvider
        </provider>
         <class>com.sap.springconcurrent.bean.Employee</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mytestdb" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="saplab" />

            <!-- EclipseLink should create the database schema automatically -->
            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.ddl-generation.output-mode" value="database" />
        </properties>

    </persistence-unit>
</persistence>

My Start :
package com.sap.springconcurrent.main;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@ContextConfiguration(locations = "classpath:spring-config.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringMainApplicationTest {

    @Autowired
    SpringMainApplication app;


    @Test
    public void test() {
        app.startApplication();
    }

}

0 个答案:

没有答案