Spring AOP Transaction - Rollback Problem

benni84

Grünschnabel
Hallo zusammen,

ich habe folgendes Problem. Tritt beim Ausführen der Methode indiziereImage(..) eine Exception auf wird kein Rollback durchgeführt. Langsam fällt mir nichts mehr ein, was ich noch ausprobieren könnte um die Transaktion samt Rollback Richtig ans laufen zu bekommen. :( Ich finde den Fehler einfach nicht.



Code:
package de.beko.imagemanager.service.impl;

import java.io.File;
import java.sql.SQLException;

import javax.management.RuntimeErrorException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import de.beko.imagemanager.ctrl.interfaces.IDirectoryScanner;
import de.beko.imagemanager.dao.interfaces.IImageDAO;
import de.beko.imagemanager.model.impl.ImageImpl;
import de.beko.imagemanager.model.interfaces.IImage;
import de.beko.imagemanager.model.interfaces.ITag;
import de.beko.imagemanager.service.interfaces.IImageService;

public class ImageServiceImpl implements IImageService {

	private final static Logger _log = LoggerFactory.getLogger(ImageServiceImpl.class);

	public ImageServiceImpl(){}

	public IImageDAO getImageDAO() {
		return _imageDAO;
	}

	public void setImageDAO(IImageDAO imageDAO) {
		_imageDAO = imageDAO;
	}

	private void addTag(ITag tag){

		_log.debug("addTag( tag:{} )", tag);

		long tagId = _imageDAO.getTagId(tag.getName());

		if(tagId == -1){
			_imageDAO.addTag(tag.getName());
		}else{
			_log.debug("Tag: {} existiert bereits", tag.getName());
		}
	}

	@Override
	public void indiziereImage(IImage image) {

		_log.info("indiziereImage( image:{} )", image.getFile().getAbsolutePath());

		File file = image.getFile();

		_log.debug("addImage( file:{} )", file.getAbsolutePath());

		try{
			long id = _imageDAO.getImageId(file.getAbsolutePath());
			_log.debug("Image existierts bereits: ID {}. Insert wird übersprungen", id);
		}catch(EmptyResultDataAccessException e){
			_imageDAO.addImage(file);
		}

		long imageId = _imageDAO.getImageId(image.getFile().getAbsolutePath());
		_imageDAO.clearTagsForImage(image.getId());

		long tagId;
		for(ITag tag : image.getTags()){
			addTag(tag);
			tagId = _imageDAO.getTagId(tag.getName());		

			_imageDAO.addImageTag(imageId, tagId);
		}
		
		testTransaction();
	}
	
	public void testTransaction(){
		throw new RuntimeException();
	}
}

Code:
<?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:tx      = "http://www.springframework.org/schema/tx"
	xmlns:context = "http://www.springframework.org/schema/context"
	xsi:schemaLocation = 
	    "http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd">
		 
	
	
	<bean id="directoryScanner" class="de.beko.imagemanager.ctrl.impl.DirectoryScanerImpl">
		<property name="fileFilter" ref="fileFilter"/>
		<property name="fileEvents">
		    <list>
		      <ref bean="imageFileIndizierenEvent"/>
		    </list>
  		</property>
	</bean>
	
	<bean id="imageFileIndizierenEvent" class="de.beko.imagemanager.ctrl.impl.ImageServiceBasedImageFileIndizierenEvent">
		<property name="imageService" ref="imageService"/>
	</bean>
	
	
	<bean id="fileFilter" class="de.beko.imagemanager.ctrl.impl.ExtensionBasedFileFilter">
		<property name="acceptedExtensions" value="jpg,jpeg"/>
	</bean>
	
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.SingleConnectionDataSource">	
		<property name="driverClassName" value="org.sqlite.JDBC"/>
		<property name="url" value="jdbc:sqlite:I:/Programmieren/Projekte/ImageManager/ImageManager/config/dev/ImageViewer.s3db"/>
	</bean>
	
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<bean id="imageDAO" class="de.beko.imagemanager.dao.impl.ImageDAOImpl">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
	
	
	<bean id="imageService" class="de.beko.imagemanager.service.impl.ImageServiceImpl">
		<property name="imageDAO" ref="imageDAO"/>
		<property name="directoryScanner" ref="directoryScanner"/>
	</bean>
	
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" rollback-for="java.lang.Exception"/>
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>
	
	<aop:config>
		<aop:pointcut id="indiziereImageServiceOperation" expression="execution(* de.beko.imagemanager.service.impl.ImageServiceImpl.indiziere*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="indiziereImageServiceOperation"/>
	</aop:config>
  
 
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
</beans>


Code:
20:13:16.382 [main] DEBUG de.beko.imagemanager.ImageManagerMain - Starte Anwendung
20:13:16.413 [main] INFO  org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@3782da3d: startup date [Wed Apr 13 20:13:16 CEST 2011]; root of context hierarchy
20:13:16.460 [main] INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [I:\Programmieren\Projekte\ImageManager\ImageManager\config\dev\imagemanager_service.xml]
20:13:16.694 [main] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6d372656: defining beans [directoryScanner,imageFileIndizierenEvent,fileFilter,dataSource,jdbcTemplate,imageDAO,imageService,txAdvice,org.springframework.aop.config.internalAutoProxyCreator,indiziereImageServiceOperation,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,txManager]; root of factory hierarchy
20:13:16.865 [main] INFO  org.springframework.jdbc.datasource.SingleConnectionDataSource - Loaded JDBC driver: org.sqlite.JDBC
20:13:16.928 [main] DEBUG de.beko.imagemanager.ImageManagerMain - Clear Tables
20:13:17.536 [main] INFO  org.springframework.jdbc.datasource.SingleConnectionDataSource - Established shared JDBC Connection: org.sqlite.Conn@4c650892
20:13:17.552 [main] DEBUG de.beko.imagemanager.service.impl.ImageServiceImpl - indiziereImage( image:C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.552 [main] INFO  de.beko.imagemanager.service.impl.ImageServiceImpl - indiziereImage( image:C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.552 [main] DEBUG de.beko.imagemanager.service.impl.ImageServiceImpl - addImage( file:C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.552 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - getImageId( C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.568 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - SELECT id FROM image WHERE full_filename = C:\Temp\TestDockland_20110308_0008.2.jpg
20:13:17.600 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - addImage( file:C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.600 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - INSERT INTO IMAGE (full_filename, last_modified) values (C:\Temp\TestDockland_20110308_0008.2.jpg, 0)
20:13:17.600 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - getImageId( C:\Temp\TestDockland_20110308_0008.2.jpg )
20:13:17.600 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - SELECT id FROM image WHERE full_filename = C:\Temp\TestDockland_20110308_0008.2.jpg
20:13:17.615 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - clearTags()
20:13:17.615 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - DELETE FROM image_tags WHERE image_id = -1
20:13:17.615 [main] DEBUG de.beko.imagemanager.dao.impl.ImageDAOImpl - DELETE FROM image_tags WHERE image_id = ?
Exception in thread "main" java.lang.RuntimeException
	at de.beko.imagemanager.service.impl.ImageServiceImpl.testTransaction(ImageServiceImpl.java:113)
	at de.beko.imagemanager.service.impl.ImageServiceImpl.indiziereImage(ImageServiceImpl.java:107)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
	at $Proxy0.indiziereImage(Unknown Source)
	at de.beko.imagemanager.ImageManagerMain.main(ImageManagerMain.java:69)
 

Thomas Darimont

Erfahrenes Mitglied
Hallo,

hmmm... wenn du get* Methoden mit read-only=true deklarierst... was möchtest du denn noch im Roll-Back machen? Btw. hast du für inidiziereImage(...) überhaupt Rollback konfiguriert?



Gruß Tom