diff --git a/src/main/java/cheat/Cheat.java b/src/main/java/cheat/Cheat.java
index 270f2fd..3eecaff 100644
--- a/src/main/java/cheat/Cheat.java
+++ b/src/main/java/cheat/Cheat.java
@@ -1,14 +1,11 @@
 package cheat;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-import javax.persistence.EntityTransaction;
+import javax.persistence.PersistenceContext;
+import javax.transaction.Transactional;
 
 import org.apache.commons.lang3.tuple.Pair;
 
@@ -22,138 +19,94 @@
 
 public class Cheat implements CheatInterfnterface {
 
-    private EntityManagerFactory emf;
-
-    public Cheat() {
-        config cfg = new config();
-        Map<String, Object> props = new HashMap<>();
-        props.put("javax.persistence.jdbc.url",
-                "jdbc:mysql://" + cfg.SqlURL + "/" + cfg.Database);
-        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
-        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
-        this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
-    }
-
-    // 测试时注入
-    public Cheat(EntityManagerFactory emf) {
-        this.emf = emf;
-    }
-
-    private EntityManager getEntityManager() {
-        return emf.createEntityManager();
-    }
+    @PersistenceContext
+    private EntityManager entityManager;
 
     @Override
+    @Transactional
     public boolean AddAppeal(Appeal appeal) {
-        EntityManager em = getEntityManager();
-        EntityTransaction tx = em.getTransaction();
         try {
-            tx.begin();
-            em.persist(appeal);
-            tx.commit();
+            entityManager.persist(appeal);
         } catch (Exception e) {
-            if (tx.isActive()) {
-                tx.rollback();
-            }
             e.printStackTrace();
             return false;
-        } finally {
-            em.close();
         }
         return true;
     }
 
     @Override
     public Appeal GetAppeal(String appealid) {
-        EntityManager em = getEntityManager();
         try {
-            JPAQueryFactory queryFactory = new JPAQueryFactory(em);
+            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
             QAppeal qAppeal = QAppeal.appeal;
             Appeal appeal = queryFactory
-                    .selectFrom(qAppeal)
-                    .where(qAppeal.appealid.eq(appealid))
-                    .fetchOne();
+                .selectFrom(qAppeal)
+                .where(qAppeal.appealid.eq(appealid))
+                .fetchOne();
             return appeal;
         } catch (Exception e) {
             e.printStackTrace();
             return null;
-        } finally {
-            em.close();
         }
     }
 
     @Override
     public Appeal[] GetAppealList() {
-        EntityManager em = getEntityManager();
         try {
-            JPAQueryFactory queryFactory = new JPAQueryFactory(em);
+            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
             QAppeal qAppeal = QAppeal.appeal;
             List<Appeal> appeals = queryFactory
-                    .selectFrom(qAppeal)
-                    .fetch();
+                .selectFrom(qAppeal)
+                .fetch();
             return appeals.toArray(new Appeal[0]);
         } catch (Exception e) {
             e.printStackTrace();
             return null;
-        } finally {
-            em.close();
         }
     }
 
     @Override
     public boolean HandleAppeal(String appealid, Integer status) {
-        EntityManager em = getEntityManager();
-        EntityTransaction tx = em.getTransaction();
         try {
-            tx.begin();
-            Appeal appeal = em.find(Appeal.class, appealid);
+            Appeal appeal = GetAppeal(appealid);
             if (appeal != null) {
                 appeal.status = status;
-                em.merge(appeal);
-                User user = em.find(User.class, appeal.appealuserid);
+                entityManager.merge(appeal);
+                User user = entityManager.find(User.class, appeal.appealuserid);
                 if (user != null && user.accountstate != false) {
                     if (status == 1) {
                         user.accountstate = false;
                     }
-                    em.merge(user);
+                    entityManager.merge(user);
                 }
-                tx.commit();
                 return true;
             }
             return false;
         } catch (Exception e) {
             e.printStackTrace();
             return false;
-        } finally {
-            if (tx.isActive()) {
-                tx.rollback();
-            }
-            em.close();
         }
     }
 
     @Override
     public Pair<String, String>[] GetFakeSeed() {
         List<Pair<String, String>> fakeSeeds = new ArrayList<>();
-        EntityManager em = getEntityManager();
         try {
-            JPAQueryFactory queryFactory = new JPAQueryFactory(em);
+            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
             QSeed qSeed = QSeed.seed;
             List<com.querydsl.core.Tuple> results = queryFactory
-                    .select(qSeed.seedid, qSeed.seeduserid)
-                    .from(qSeed)
-                    .where(qSeed.faketime.gt(new config().FakeTime))
-                    .fetch();
+                .select(qSeed.seedid, qSeed.seeduserid)
+                .from(qSeed)
+                .where(qSeed.faketime.gt(new config().FakeTime))
+                .fetch();
             for (com.querydsl.core.Tuple result : results) {
                 String seedid = result.get(qSeed.seedid);
-                String userid  = result.get(qSeed.seeduserid);
+                String userid = result.get(qSeed.seeduserid);
                 fakeSeeds.add(Pair.of(seedid, userid));
             }
         } catch (Exception e) {
             e.printStackTrace();
             return null;
-        } finally {
-            em.close();
         }
         return fakeSeeds.toArray(new Pair[0]);
     }
@@ -161,23 +114,20 @@
     @Override
     public String[] GetPunishedUserList() {
         List<String> punishedUsers = new ArrayList<>();
-        EntityManager em = getEntityManager();
         try {
-            JPAQueryFactory queryFactory = new JPAQueryFactory(em);
+            JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
             entity.QUser qUser = entity.QUser.user;
             List<String> results = queryFactory
-                    .select(qUser.userid)
-                    .from(qUser)
-                    .where(qUser.accountstate.isTrue())
-                    .fetch();
+                .select(qUser.userid)
+                .from(qUser)
+                .where(qUser.accountstate.isTrue())
+                .fetch();
             for (String userid : results) {
                 punishedUsers.add(userid);
             }
         } catch (Exception e) {
             e.printStackTrace();
             return null;
-        } finally {
-            em.close();
         }
         return punishedUsers.toArray(new String[0]);
     }
@@ -198,17 +148,21 @@
 
         //     int n = tasks.size();
         //     if (n == 0) continue;
+
         //     double[] xArr = new double[n];
         //     for (int i = 0; i < n; i++) {
         //         TransRecord t = tasks.get(i);
         //         xArr[i] = Math.max(0, t.upload - t.download);
         //     }
+
         //     double sum = 0;
         //     for (double x : xArr) sum += x;
         //     double mu = sum / n;
+
         //     double sqSum = 0;
         //     for (double x : xArr) sqSum += (x - mu) * (x - mu);
         //     double sigma = Math.sqrt(sqSum / n);
+
         //     for (int i = 0; i < n; i++) {
         //         if (Math.abs(xArr[i] - mu) > 3 * sigma) {
         //             User user = entityManager.find(User.class, tasks.get(i).downloaduserid);
@@ -223,37 +177,27 @@
     }
 
     @Override
-    public void DetectFakeSeed() {
+    public void DetectFakeSeed(){
     }
 
     @Override
-    public boolean DetectFakeSeed(String seedid) {
+    public boolean DetectFakeSeed(String seedid){
         return false;
     }
 
     @Override
-    public void PunishUser() {
-        EntityManager em = getEntityManager();
-        EntityTransaction tx = em.getTransaction();
-        try {
-            tx.begin();
-            JPAQueryFactory queryFactory = new JPAQueryFactory(em);
-            entity.QUser qUser = entity.QUser.user;
-            List<User> users = queryFactory
-                    .selectFrom(qUser)
-                    .where(qUser.detectedCount.gt(new entity.config().CheatTime)
-                            .or(qUser.fakeDetectedCount.gt(new entity.config().FakeTime)))
-                    .fetch();
+    public void PunishUser(){
+        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
+        entity.QUser qUser = entity.QUser.user;
+        List<User> users = queryFactory
+            .selectFrom(qUser)
+            .where(qUser.detectedCount.gt(new entity.config().CheatTime) 
+                .or(qUser.fakeDetectedCount.gt(new entity.config().FakeTime)))
+            .fetch();
 
-            for (User user : users) {
-                user.accountstate = true;
-                em.merge(user);
-            }
-            tx.commit();
-        } catch (Exception e) {
-            if (tx.isActive()) tx.rollback();
-        } finally {
-            em.close();
+        for (User user : users) {
+            user.accountstate = true;
+            entityManager.merge(user);
         }
     }
-}
+}
\ No newline at end of file
