Table des matières
Contenu de la question
Solution
Maison Java Lorsque vous essayez de démarrer deux tâches Spring Batch ou plus en même temps, une erreur est générée : ORA-08177 : Impossible de sérialiser l'accès pour cette transaction

Lorsque vous essayez de démarrer deux tâches Spring Batch ou plus en même temps, une erreur est générée : ORA-08177 : Impossible de sérialiser l'accès pour cette transaction

Feb 09, 2024 pm 05:00 PM
lsp

L'éditeur php Xigua peut rencontrer un problème lors de l'utilisation de Spring Batch : lorsque vous essayez de démarrer deux ou plusieurs tâches Spring Batch en même temps, une erreur sera générée : ORA-08177 : Impossible de sérialiser l'accès à cette transaction. Cette erreur peut prêter à confusion, mais elle est en réalité causée par un problème de verrouillage de la base de données. Avant de résoudre ce problème, nous devons comprendre certaines connaissances de base sur Spring Batch et les transactions de base de données.

Contenu de la question

J'ai rencontré une erreur en essayant d'utiliser completablefuture pour exécuter deux tâches Spring Batch en parallèle. Le message d'erreur est le suivant :

originalsql = insert into batch_job_instance(job_instance_id, job_name, job_key, version)
    values (?, ?, ?, ?)
, error msg = ora-08177: can't serialize access for this transaction
Copier après la connexion

J'utilise Spring Batch 5.x, Spring Boot 3.1.6, JDK 17

Propriétés de l'application

spring.batch.repository.isolationlevelforcreate=isolation_read_committed
spring.batch.isolationlevel=read_committed
spring.batch.jdbc.table-prefix=batch_
spring.batch.job.enabled=false
Copier après la connexion

batchconfig.java

@configuration
public class batchconfig {

@bean("simpletaskexecutor")
    public taskexecutor simpletaskexecutor() {
        simpleasynctaskexecutor asynctaskexecutor = new simpleasynctaskexecutor("simpletaskexecutor");
        asynctaskexecutor.setconcurrencylimit(concurrencycount);
        return asynctaskexecutor;
    }


@bean("joblauncherasync")
    @scope("prototype")
    public joblauncher joblauncherasync(datasource datasource, jobrepository jobrepository) throws exception {

        taskexecutorjoblauncher joblauncher = new taskexecutorjoblauncher();
        joblauncher.setjobrepository(jobrepository);
        joblauncher.settaskexecutor(simpletaskexecutor());
        joblauncher.afterpropertiesset();
        return joblauncher;
    }
    
    @bean
    public jpatransactionmanager transactionmanager(entitymanagerfactory entitymanagerfactory) {
        return new jpatransactionmanager(entitymanagerfactory);
    }
    
    @bean
    public batchjobexecutionlistener batchjobexecutionlistener() {
        return new batchjobexecutionlistener();
    } 
    
    @bean
    public batchjobstepexecutionlistner batchjobstepexecutionlistner() {
        return new batchjobstepexecutionlistner();
    }
Copier après la connexion

}

employeejobconfig.java

@configuration
@import(batchconfig.class)
public class employeejobconfig{
    
        
    @autowired
    employeestatuswritter employeestatuswritter;
    
    @autowired
    employeependingprocessor employeependingprocessor;
    
    
    
    @bean("employeependingreader")
    public jpapagingitemreader<employee> employeependingreader(datasource ds,entitymanagerfactory entitymanagerfactory) {
        
        jpapagingitemreader<employee> jpareader = new jpapagingitemreader<>();
        jpareader.setentitymanagerfactory(entitymanagerfactory);
        jpareader.setquerystring("select e from employee e");
        jpareader.setpagesize(5000);
        return jpareader;

    }
    
    @bean("employeespinvokestep")
    public step employeespinvokestep(@qualifier("employeependingreader") itemreader<employee> reader,
            @qualifier("employeestatuswritter") itemwriter<employee> writer,
            @qualifier("employeependingprocessor") itemprocessor<employee, employee> processor,jobrepository jobrepository,
            platformtransactionmanager transactionmanager,batchjobstepexecutionlistner batchjobstepexecutionlistner,taskexecutor simpletaskexecutor) {

        return new stepbuilder("employeespinvokestep",jobrepository)
                .<employee, employee>chunk(50,transactionmanager).reader(reader)
                .processor(processor).writer(writer)
                .listener(batchjobstepexecutionlistner)
                .taskexecutor(simpletaskexecutor)
                .build();
    }
    
    @bean("employeespjob")
    public job employeespjob(@qualifier("employeespinvokestep") step employeespinvokestep,jobrepository jobrepository,batchjobexecutionlistener batchjobexecutionlistener) {
        return new jobbuilder("employeespjob",jobrepository)
                .incrementer(new runidincrementer())
                .listener(batchjobexecutionlistener)
                .start(employeespinvokestep)
                .build();
    }

}
Copier après la connexion

managerconfig.java

@configuration
@import(batchconfig.class)
public class managerconfig {
    
        

    @autowired
    managerstatuswritter managerstatuswritter;
    
    
    @autowired
    managerpendingprocessor managerpendingprocessor;
    
    @bean("managerpendingreader")
    public jpapagingitemreader<manager> managerpendingreader(datasource ds,entitymanagerfactory entitymanagerfactory) {
        
        jpapagingitemreader<manager> jpareader = new jpapagingitemreader<>();
        jpareader.setentitymanagerfactory(entitymanagerfactory);
        jpareader.setquerystring("select m from manager m");
        jpareader.setpagesize(5000);
        return jpareader;

    }
    
    @bean("managerspinvokestep")
    public step indvinvoiceconsctlspinvokestep(@qualifier("managerpendingreader") itemreader<manager> reader,
            @qualifier("managerstatuswritter") itemwriter<manager> writer,
            @qualifier("managerpendingprocessor") itemprocessor<manager, manager> processor,jobrepository jobrepository,
            platformtransactionmanager transactionmanager,batchjobstepexecutionlistner batchjobstepexecutionlistner,taskexecutor simpletaskexecutor) {

        return new stepbuilder("managerspinvokestep",jobrepository)
                .<manager, manager>chunk(5000,transactionmanager).reader(reader)
                .processor(processor).writer(writer)
                .listener(batchjobstepexecutionlistner)
                .taskexecutor(simpletaskexecutor)
                .build();
    }
    
    @bean("managerspjob")
    public job managerspjob(@qualifier("managerspinvokestep") step indvinvoiceconsctlspinvokestep,jobrepository jobrepository,batchjobexecutionlistener batchjobexecutionlistener) {
        return new jobbuilder("managerspjob",jobrepository)
                .incrementer(new runidincrementer())
                .listener(batchjobexecutionlistener)
                .start(indvinvoiceconsctlspinvokestep)
                .build();
    }
    
}
Copier après la connexion

batchjobmanager.java

@service
public class batchjobmanager {

    
    
      @autowired applicationcontext context;
     
      @autowired batchexecutorservice batchexecutorservice;
      
      @autowired
      batchjobrunner batchjobrunner;
      
       
    
    public void startjob() {
        
         try {
               system.out.println("batchjobmanager called .. "+new date());
                
               string[] invoicenames={"employeespjob","managerspjob"};
               
               list<string> invoicenameslist = arrays.aslist(invoicenames);
               launchasyn(getbatchjoblist(invoicenameslist));
                
                 
         } catch (exception e) {
             system.out.println("while loading job..");
             e.printstacktrace();
         }
        
    }
      

    public list<batchjob>  getbatchjoblist(list<string> jobnames) throws exception{
        list<batchjob> batchjoblist=new arraylist<batchjob>();
        for(string job:jobnames) {
             batchjob batchjob= batchjob.builder().jobname(invoicejob).build();
             batchjoblist.add(batchjob);
        }
        return batchjoblist;
    }
      
    
       
    public void launchasyn( list<batchjob> batchjoblist) throws exception{
         list<completablefuture<batchjob>> batchjobfuturelist = new arraylist<completablefuture<batchjob>>();
          
          for(batchjob batchjob:batchjoblist) {
          completablefuture<batchjob> jobfuture = batchexecutorservice.execute(batchjob, asynctaskexecutor);
          batchjobfuturelist.add(jobfuture);
          }
          
          completablefuture<void> jobfutureresult = completablefuture
                    .allof(batchjobfuturelist.toarray(new completablefuture[batchjobfuturelist.size()]));
          
          
          completablefuture<list<canbatchjob>> allcompletablefuture = jobfutureresult.thenapply(future -> {
                return batchjobfuturelist.stream().map(completablefuture -> completablefuture.join())
                        .collect(collectors.tolist());
            });
        
          list<batchjob> resultfuturelist=allcompletablefuture.get();
          
          for(batchjob batch:resultfuturelist) {
              system.out.println("status "+batch.getiscompleted());
          }
    }
   
    
}
Copier après la connexion

batchexecutorservice.java

@service
public class batchexecutorservice {
    
        
    @autowired 
    batchjobrunner batchjobrunner;
        
    public completablefuture<canbatchjob> execute(canbatchjob canbatchjob,taskexecutor threadpooltaskexecutor){
        return completablefuture.supplyasync(() -> batchjobrunner.execute(canbatchjob),threadpooltaskexecutor);
    }
    
    
}
Copier après la connexion

batchjobrunner.java

@service
public class batchjobrunner {

    @autowired applicationcontext context;
      
    
     @autowired 
     @qualifier("joblauncherasync")
     joblauncher joblauncherasync;
    
    
    /*
     * @autowired joblauncher joblauncherasync;
     */
    
    public batchjob execute(batchjob batchjob) {
        try {
            system.out.println(" batchjob"+batchjob.getjobname()+" called ...");
            joblauncherasync.run(getjob(batchjob.getjobname()), getjobparameters(batchjob.getjobname()));
            thread.sleep(15000);
            batchjob.setiscompleted(true);
            system.out.println(" batchjob"+batchjob.getjobname()+" completed ...");
        }
        catch(exception e) {
            system.out.println("exception "+e.getmessage());
            batchjob.seterrordesc(e.getmessage().tostring());
            e.printstacktrace();
        }
        
        return canbatchjob;
    }
    
    public job getjob(string jobname) {
        
         return  (job) context.getbean(jobname); 
    }
    
    public jobparameters getjobparameters(string jobname) {
    
    jobparameters  jobparameters = new jobparametersbuilder() .addstring("unique_id",
              uuid.randomuuid().tostring(), true) .addstring("job_name", jobname,
              true) .adddate("execution_start_date", date.from(instant.now()),
              true).tojobparameters();
    return jobparameters;
    }
    
}
Copier après la connexion

batchjob.java

public class BatchJob {

    private String jobName;
    private Boolean isCompleted;
    private String errorDesc;
    
    
}
Copier après la connexion

Les tâches s'exécutent avec succès lorsqu'elles sont exécutées une par une ou dans l'ordre. Cependant, lors de l'utilisation de completeablefuture, j'ai rencontré un problème. Est-ce que démarrer les travaux par lots de printemps en même temps est la bonne manière ?

Solution

1. Ajoutez les propriétés suivantes à application.properties

.

spring.main.allow-bean-definition-overriding=true

2. Joblauncher() mis à jour, comme indiqué dans batchconfig.java ci-dessous

@bean("joblauncher")
    public joblauncher joblauncher(datasource datasource, jobrepository jobrepository) throws exception {
        taskexecutorjoblauncher joblauncher = new taskexecutorjoblauncher();
        joblauncher.setjobrepository(jobrepository);
        joblauncher.settaskexecutor(simpletaskexecutor());
        joblauncher.afterpropertiesset();
        return joblauncher;
    }
Copier après la connexion
  • Suppression de completeablefuture.

  • batchexecutorservice.java supprimé

  • Ajout des méthodes suivantes dans batchjobmanager.java pour appeler des tâches.

    public void launchSync(List<BatchJob> batchJobList) throws Exception {
             for(BatchJob batchJob:batchJobList) {
                  batchJobRunner.execute(batchJob);
                  }  
         }
    Copier après la connexion

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

  • Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

    Outils d'IA chauds

    Undresser.AI Undress

    Undresser.AI Undress

    Application basée sur l'IA pour créer des photos de nu réalistes

    AI Clothes Remover

    AI Clothes Remover

    Outil d'IA en ligne pour supprimer les vêtements des photos.

    Undress AI Tool

    Undress AI Tool

    Images de déshabillage gratuites

    Clothoff.io

    Clothoff.io

    Dissolvant de vêtements AI

    Video Face Swap

    Video Face Swap

    Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

    Outils chauds

    Bloc-notes++7.3.1

    Bloc-notes++7.3.1

    Éditeur de code facile à utiliser et gratuit

    SublimeText3 version chinoise

    SublimeText3 version chinoise

    Version chinoise, très simple à utiliser

    Envoyer Studio 13.0.1

    Envoyer Studio 13.0.1

    Puissant environnement de développement intégré PHP

    Dreamweaver CS6

    Dreamweaver CS6

    Outils de développement Web visuel

    SublimeText3 version Mac

    SublimeText3 version Mac

    Logiciel d'édition de code au niveau de Dieu (SublimeText3)

    Comment cacher un album photo sur Redmi Note13RPro ? Comment cacher un album photo sur Redmi Note13RPro ? May 01, 2024 pm 12:50 PM

    RedmiNote13RPro est un nouveau modèle avec de très bonnes performances et configuration. Ce téléphone dispose d'une fonction d'album photo caché très utile. Il peut aider les utilisateurs à masquer leurs albums photo afin que les autres ne puissent pas voir vos albums photo. Ensuite, l'éditeur vous expliquera comment masquer l'album photo sur Redmi Note13R Pro pour vous aider à protéger votre vie privée. Comment cacher un album photo sur Redmi Note13RPro ? 1. Entrez les paramètres de votre téléphone Xiaomi. 2. Cliquez ensuite sur Confidentialité et protection. 3. Cliquez à nouveau sur Protéger la confidentialité ici. 4. Cliquez sur le coffre-fort. 5. Enfin, vous pouvez créer ici un album photo privé. Questions fréquemment posées : connectez Bluetooth, modifiez le thème de la méthode de saisie, modifiez les paramètres d'usine, masquez les applications, mettez en miroir le téléviseur, NFC, activez l'installation double SIM, l'heure d'activation

    Comment ajuster la taille de la police sur Redmi Note13RPro ? Comment ajuster la taille de la police sur Redmi Note13RPro ? May 07, 2024 pm 06:34 PM

    Ne changez pas la signification du contenu original, affinez le contenu, réécrivez le contenu, ne continuez pas. Redmi Note13RPro a non seulement d'excellentes performances, mais offre également une expérience utilisateur encore meilleure afin de donner à chacun une expérience plus confortable. , Redmi Note13RPro est équipé d'une fonction de réglage des polices pour permettre aux utilisateurs de pouvoir ajuster les polices de votre téléphone. Si vous voulez savoir comment ajuster la taille de la police du Redmi Note13R Pro, jetez-y un œil. Comment ajuster la taille de la police sur Redmi Note13RPro ? 1. Ouvrez l'application Paramètres. 2. Faites défiler vers le bas et sélectionnez « Affichage ». 3. Cliquez sur "Taille du texte". 4. Sur cet écran, vous pouvez ajuster la taille de la police en faisant glisser le curseur ou en sélectionnant une taille de police prédéfinie. 5. Une fois le réglage terminé, appuyez sur "OK" pour enregistrer

    Comment connecter Redmi Note13RPro à l'ordinateur ? Comment connecter Redmi Note13RPro à l'ordinateur ? May 09, 2024 pm 06:52 PM

    Redmi Note13RPro est un téléphone mobile très populaire récemment. De nombreux consommateurs ont acheté ce téléphone. Cependant, de nombreux utilisateurs utilisent ce téléphone pour la première fois et ne savent donc pas comment connecter Redmi Note13RPro à l'ordinateur. L'éditeur est là pour vous expliquer. Une introduction détaillée du didacticiel est fournie. Comment connecter Redmi Note13RPro à l’ordinateur ? 1. Utilisez un câble de données USB pour connecter le téléphone Redmi à l'interface USB de l'ordinateur. 2. Ouvrez les paramètres du téléphone, cliquez sur Options et activez le débogage USB. 3. Ouvrez le gestionnaire de périphériques sur votre ordinateur et recherchez l'option de périphérique mobile. 4. Cliquez avec le bouton droit sur le périphérique mobile, sélectionnez Mettre à jour le pilote, puis sélectionnez Rechercher automatiquement les pilotes mis à jour. 5. Si l'ordinateur ne recherche pas automatiquement le pilote,

    Comment désactiver le son de la caméra sur Redmi Note13RPro ? Comment désactiver le son de la caméra sur Redmi Note13RPro ? May 02, 2024 pm 06:31 PM

    La fonction appareil photo du Redmi Note13RPro est très simple à utiliser, notamment lors de la prise de photos, elle simulera le son de l'obturateur de l'appareil photo. Cependant, cette fonction peut déranger les autres dans des situations calmes comme les bibliothèques, c'est pourquoi de nombreux utilisateurs veulent savoir comment tourner. désactiver le son de la caméra de Redmi Note13RPro, laissez l'éditeur vous le dire ci-dessous. Comment désactiver le son de la caméra sur Redmi Note13RPro ? 1. Pour la première méthode, vous devez d’abord ouvrir les paramètres de votre téléphone. 2. Recherchez ensuite les applications système dans le menu des paramètres. 3. Ensuite, nous trouvons l’option caméra sous l’interface de l’application système. 4. Enfin, nous pouvons définir s'il faut désactiver le son de la caméra dans l'interface de la caméra. Il nous suffit d'éteindre l'interrupteur sur le côté droit du son de la caméra. 5. La deuxième méthode, la première étape, ouvrez

    Comment extraire le texte des images sur Redmi Note13RPro ? Comment extraire le texte des images sur Redmi Note13RPro ? May 08, 2024 pm 10:00 PM

    Le téléphone mobile Redmi Note13RPro intègre un certain nombre d'outils intelligents en termes de fonctions logicielles, parmi lesquels l'extraction rapide et précise du contenu du texte des images. L'éditeur suivant vous présentera comment Redmi Note13RPro extrait le texte des images. Comment extraire le texte des images sur Redmi Note13RPro ? Utilisez la fonction de numérisation de code QR Xiaomi, ouvrez l'application de numérisation de code QR sur votre téléphone, cliquez sur l'icône d'image, sélectionnez une image, puis cliquez sur l'option « Reconnaître le texte » à droite pour extraire avec succès le texte de l'image. Fonctionner via l'album du téléphone mobile. Recherchez l'image dont le texte doit être extrait dans l'album du téléphone mobile, cliquez sur « Plus » sous l'image et sélectionnez « Extraire le texte ». Après une reconnaissance réussie, vous pouvez copier ou enregistrer le texte selon vos besoins. Utilisez les mini-programmes WeChat. Micro ouvert

    Un guide complet à tous les niveaux de 'Whole Life' Un guide complet à tous les niveaux de 'Whole Life' May 07, 2024 pm 06:31 PM

    Whole Huoba est un jeu de réflexion décontracté très amusant que tout le monde peut découvrir sur plusieurs plateformes ! Le jeu propose d'innombrables niveaux passionnants qui attendent d'être débloqués. Chaque niveau est plein de nouveautés et de défis, vous permettant de vivre une aventure intéressante en répondant à des questions et en déverrouillant du nouveau contenu de jeu. Alors comment effacer tout le niveau de Huoba ? Aujourd'hui je vous propose un guide complet de tous les niveaux de "Whole Life". Si vous rencontrez des problèmes pour réussir le niveau, vous pouvez vous y référer ! "The Whole Life" guide complet pour tous les niveaux de "The Whole Life" Le guide complet pour tous les niveaux de "The Whole Life" Aidez-la à regarder le réveillon du Nouvel An, aidez la petite sœur à identifier le salaud de loup et la grand-mère aide la petite fille à échapper au danger pour une aventure en plein air, en faisant semblant de ne pas voir Ah Piao et en se transformant. L'humanoïde a aidé l'orang-outan à devenir un humanoïde. Quelqu'un sur la banquette arrière est resté calme et s'est occupé du fantôme féminin. calmez-vous et traitez le fantôme féminin.

    Comment paramétrer l'affichage du trafic sur Redmi Note13RPro ? Comment paramétrer l'affichage du trafic sur Redmi Note13RPro ? May 02, 2024 pm 03:34 PM

    RedmiNote13RPro est un téléphone mobile apprécié par la majorité des utilisateurs. Ce téléphone fournit une méthode spéciale pour afficher le trafic sur le téléphone. Si vous ne savez toujours pas comment configurer RedmiNote13RPro pour afficher le trafic, suivez l'éditeur pour le savoir. Comment paramétrer l’affichage du trafic sur Redmi Note13RPro ? 1. Entrez « Paramètres » et cliquez sur « Réseau mobile double SIM ». 2. Faites défiler vers le bas pour sélectionner l'option « Paramètres du package de données ». 3. Activez les commutateurs de fonction sur le côté droit de « Afficher les informations routières dans la barre de notification » et « Afficher la vitesse actuelle du réseau dans la barre d'état ». 4. Une fois le réglage réussi, déroulez la barre d'état pour voir l'affichage de la vitesse du réseau et des informations routières en temps réel. FAQ Connecter Bluetooth Modifier le thème de la méthode de saisie Modifier les paramètres d'usine Masquer la diffusion de l'application

    'Whole Life' Journey to the West Beauty aide les personnages féminins de Journey to the West à retourner chez eux et clarifie la stratégie 'Whole Life' Journey to the West Beauty aide les personnages féminins de Journey to the West à retourner chez eux et clarifie la stratégie May 07, 2024 pm 03:46 PM

    Whole Huoba est un jeu de niveau amusant très populaire sur Douyin. Il existe de nombreux niveaux dans le jeu qui attendent que tout le monde les défie ! Dans le niveau de jeu « Journey to the West Beauty », tout le monde doit aider le personnage féminin de « Journey to the West » à revenir à son poste. Comment passer le niveau ? Ce qui suit est un guide pour vous permettre de terminer le niveau de "Vie entière" dans "Journey to the West" où les beautés aident les personnages féminins de "Journey to the West" à retourner à leur place. passez le niveau, jetons un oeil. J'espère que cela pourra vous aider. La beauté de "Whole Life" Journey to the West aide le personnage féminin de Journey to the West à revenir à sa place. La beauté de Journey to the West aide le personnage féminin de Journey to the West à revenir à sa place. 1. Cliquez sur le parchemin pour faire apparaître le personnage féminin. 2. L'esprit des os blancs et l'esprit du paon doivent cliquer pour changer d'action. 3. La réponse est celle indiquée dans la figure ci-dessous : "Toute la vie". Live" a un guide complet pour tous les niveaux, l'aidant à être l'observatrice de l'année, aidant la petite sœur à identifier le salaud et le loup, et la grand-mère à aider la petite fille à échapper au danger et à vivre des aventures en plein air.