1

春と休止状態を使用しています。トランザクション管理に春を使用しています。私はクラスの下にあります。

@Service
@Transactional(readOnly = true)
public class Sample implements SampleInterface{

@Override
public List<Some> getData(){

//gets data after that it updates something

setStatus(someId);

}

@Override
@Transactional
public void setStatus(Long someId){

//sets status

}

}

getData() の @Transactional を保持しないと、例外が発生します。

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode

getData() の @Transactional を保持すると、適切に保存されます。ここで何が問題ですか?どのように私は setStatus() の @Transactional を持っています。ステータスを設定するパブリックメソッドを呼び出しているため、 getData() の @Transactional を保持する必要がありますか?

ありがとう!

4

2 に答える 2

5

この問題は少し複雑で、setStatus() 内部 getData()での呼び出しが原因です。getData()外部から呼び出している場合、実際には Spring フレームワークによって作成された Java プロキシを呼び出しています。このプロキシは、トランザクションの動作 (読み取り専用トランザクションを開始) を適用し、実際のサービス クラスに委任します。これはうまくいきます。

ただし、 を呼び出すとsetStatus()、トランザクション プロキシをバイパスしてサービスを直接呼び出すことになります。つまり、へのリクエストsetStatus()は傍受されず、@Transactional 無視されます。

この問題に対処する簡単な方法はなく、にも同じ問題があります。同じクラス内でパブリック メソッドを呼び出すときは、特に注意する必要があります。

こちらもご覧ください

于 2012-08-14T11:09:32.657 に答える
1

getData を呼び出すと (メソッドに @Transactional なしで)、Spring は読み取り専用トランザクションを開始します。これがクラスのデフォルトであり、getData が setStatus を呼び出すと、Spring は新しいトランザクションを作成する代わりに既存の rad のみのトランザクションを使用します。それが例外を取得している理由です。

デフォルトのトランザクション伝搬は PROPAGATION REQUIRED です。このトピックの詳細については、http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#tx-propagationを参照してください。

于 2012-08-14T11:14:01.033 に答える